--- contrib/unbound/.github/FUNDING.yml.orig
+++ contrib/unbound/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: ['https://nlnetlabs.nl/funding/']
--- contrib/unbound/.travis.yml.orig
+++ contrib/unbound/.travis.yml
@@ -0,0 +1,16 @@
+sudo: false
+language: c
+compiler:
+  - gcc
+addons:
+  apt:
+    packages:
+    - libssl-dev
+    - libevent-dev
+    - libexpat-dev
+    - clang
+script:
+  - ./configure --enable-debug --disable-flto
+  - make
+  - make test
+  - (cd testdata/clang-analysis.tdir; bash clang-analysis.test)
--- contrib/unbound/Makefile.in.orig
+++ contrib/unbound/Makefile.in
@@ -110,6 +110,7 @@
 iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \
 iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
 services/localzone.c services/mesh.c services/modstack.c services/view.c \
+services/rpz.c \
 services/outbound_list.c services/outside_network.c util/alloc.c \
 util/config_file.c util/configlexer.c util/configparser.c \
 util/shm_side/shm_main.c services/authzone.c \
@@ -126,7 +127,7 @@
 edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
 edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
 cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
+$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
 COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
 as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
 iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
@@ -135,11 +136,11 @@
 fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
 random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
 slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
-autotrust.lo val_anchor.lo \
+autotrust.lo val_anchor.lo rpz.lo \
 validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
 val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
 $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
-$(IPSECMOD_OBJ) respip.lo
+$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
 COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
 outside_network.lo
 COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@@ -148,7 +149,7 @@
 COMPAT_SRC=compat/ctime_r.c compat/fake-rfc2553.c compat/gmtime_r.c \
 compat/inet_aton.c compat/inet_ntop.c compat/inet_pton.c compat/malloc.c \
 compat/memcmp.c compat/memmove.c compat/snprintf.c compat/strlcat.c \
-compat/strlcpy.c compat/strptime.c compat/getentropy_linux.c \
+compat/strlcpy.c compat/strptime.c compat/getentropy_freebsd.c compat/getentropy_linux.c \
 compat/getentropy_osx.c compat/getentropy_solaris.c compat/getentropy_win.c \
 compat/explicit_bzero.c compat/arc4random.c compat/arc4random_uniform.c \
 compat/arc4_lock.c compat/sha512.c compat/reallocarray.c compat/isblank.c \
@@ -160,6 +161,7 @@
 sldns/parseutil.c sldns/rrdef.c sldns/str2wire.c
 SLDNS_OBJ=keyraw.lo sbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \
 str2wire.lo
+SLDNS_ALLOCCHECK_EXTRA_OBJ=@SLDNS_ALLOCCHECK_EXTRA_OBJ@
 UNITTEST_SRC=testcode/unitanchor.c testcode/unitdname.c \
 testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \
 testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \
@@ -187,11 +189,11 @@
 $(SLDNS_OBJ) $(COMPAT_OBJ) @WIN_CONTROL_OBJ_LINK@
 HOST_SRC=smallapp/unbound-host.c
 HOST_OBJ=unbound-host.lo
-HOST_OBJ_LINK=$(HOST_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ_WITHOUT_CTIMEARC4) @WIN_HOST_OBJ_LINK@
+HOST_OBJ_LINK=$(HOST_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ_WITHOUT_CTIMEARC4) $(SLDNS_ALLOCCHECK_EXTRA_OBJ) @WIN_HOST_OBJ_LINK@
 UBANCHOR_SRC=smallapp/unbound-anchor.c
 UBANCHOR_OBJ=unbound-anchor.lo
 UBANCHOR_OBJ_LINK=$(UBANCHOR_OBJ) parseutil.lo \
-$(COMPAT_OBJ_WITHOUT_CTIME) @WIN_UBANCHOR_OBJ_LINK@
+$(COMPAT_OBJ_WITHOUT_CTIME) $(SLDNS_ALLOCCHECK_EXTRA_OBJ) @WIN_UBANCHOR_OBJ_LINK@
 TESTBOUND_SRC=testcode/testbound.c testcode/testpkts.c \
 daemon/worker.c daemon/acl_list.c \
 daemon/daemon.c daemon/stats.c \
@@ -217,7 +219,7 @@
 $(SLDNS_OBJ)
 ASYNCLOOK_SRC=testcode/asynclook.c
 ASYNCLOOK_OBJ=asynclook.lo
-ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ)
+ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ) @ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ@
 STREAMTCP_SRC=testcode/streamtcp.c
 STREAMTCP_OBJ=streamtcp.lo
 STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
@@ -229,6 +231,8 @@
 DELAYER_OBJ=delayer.lo
 DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
 $(SLDNS_OBJ)
+IPSET_SRC=@IPSET_SRC@
+IPSET_OBJ=@IPSET_OBJ@
 LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \
 libunbound/libworker.c
 LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo
@@ -256,8 +260,9 @@
 	$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
 	$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
 	$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) \
-	$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\
+	$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
 	$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
+
 ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
 	$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
 	$(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
@@ -452,14 +457,19 @@
 	rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
 	rm -rf autom4te.cache .libs build doc/html doc/xml
 
-realclean: clean
-	rm -f config.status config.log config.h.in config.h
-	rm -f configure config.sub config.guess ltmain.sh aclocal.m4 libtool
-	rm -f util/configlexer.c util/configparser.c util/configparser.h
-	rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5
+distclean: clean
+	rm -f config.status config.log config.h
+	rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5 doc/unbound-host.1
+	rm -f smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service
 	rm -f $(TEST_BIN)
 	rm -f Makefile 
 
+maintainer-clean: distclean
+	rm -f util/configlexer.c util/configparser.c util/configparser.h
+
+realclean: maintainer-clean
+	rm -f configure config.h.in config.sub config.guess ltmain.sh aclocal.m4 libtool
+
 .SUFFIXES: .lint
 .c.lint:
 	$(LINT) $(LINTFLAGS) -I. -I$(srcdir) $<
@@ -482,9 +492,9 @@
 	if test -n "$(doxygen)"; then \
 		$(doxygen) $(srcdir)/doc/unbound.doxygen; fi
 	if test "$(WITH_PYUNBOUND)" = "yes" -o "$(WITH_PYTHONMODULE)" = "yes"; \
-	    then if test -x "`which sphinx-build 2>&1`"; then \
-		sphinx-build -b html pythonmod/doc doc/html/pythonmod; \
-		sphinx-build -b html libunbound/python/doc doc/html/pyunbound;\
+	    then if test -x "`which sphinx-build-$(PY_MAJOR_VERSION) 2>&1`"; then \
+		sphinx-build-$(PY_MAJOR_VERSION) -b html pythonmod/doc doc/html/pythonmod; \
+		sphinx-build-$(PY_MAJOR_VERSION) -b html libunbound/python/doc doc/html/pyunbound;\
 	    fi ;\
 	fi
 
@@ -613,6 +623,8 @@
 			-e 's?$$(srcdir)/util/configparser.c?util/configparser.c?g' \
 			-e 's?$$(srcdir)/util/configparser.h?util/configparser.h?g' \
 			-e 's?$$(srcdir)/dnstap/dnstap_config.h??g' \
+			-e 's?$$(srcdir)/dnstap/dnstap.pb-c.c?dnstap/dnstap.pb-c.c?g' \
+			-e 's?$$(srcdir)/dnstap/dnstap.pb-c.h?dnstap/dnstap.pb-c.h?g' \
 			-e 's?$$(srcdir)/dnscrypt/dnscrypt_config.h??g' \
 			-e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
 			-e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
@@ -631,76 +643,79 @@
 	fi
 	rm -f $(DEPEND_TMP) $(DEPEND_TMP2)
 
+# build rules
+ipset.lo ipset.o: $(srcdir)/ipset/ipset.c
+
 # Dependencies
 dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
- $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/services/cache/dns.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/validator/val_nsec.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
 infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h \
  $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h \
  $(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
  $(srcdir)/sldns/pkthdr.h
 rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/net_help.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h
 as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
 dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/storage/lookup3.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/storage/lookup3.h $(srcdir)/sldns/sbuffer.h
 msgencode.lo msgencode.o: $(srcdir)/util/data/msgencode.c config.h $(srcdir)/util/data/msgencode.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h \
- $(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/services/view.h
 msgparse.lo msgparse.o: $(srcdir)/util/data/msgparse.c config.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h \
- $(srcdir)/util/regional.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
 msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/module.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/module.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
+ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/respip/respip.h
 packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h \
- $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
 iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.h $(srcdir)/iterator/iterator.h \
  $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_hints.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_scrub.h \
- $(srcdir)/iterator/iter_priv.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/services/authzone.h \
- $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_utils.h \
+ $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_donotq.h \
+ $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_scrub.h $(srcdir)/iterator/iter_priv.h \
+ $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
  $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h
 iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h $(srcdir)/iterator/iter_delegpt.h \
  $(srcdir)/util/log.h $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
 iter_donotq.lo iter_donotq.o: $(srcdir)/iterator/iter_donotq.c config.h $(srcdir)/iterator/iter_donotq.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h
@@ -707,121 +722,138 @@
 iter_fwd.lo iter_fwd.o: $(srcdir)/iterator/iter_fwd.c config.h $(srcdir)/iterator/iter_fwd.h \
  $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
  $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
 iter_hints.lo iter_hints.o: $(srcdir)/iterator/iter_hints.c config.h $(srcdir)/iterator/iter_hints.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/wire2str.h
 iter_priv.lo iter_priv.o: $(srcdir)/iterator/iter_priv.c config.h $(srcdir)/iterator/iter_priv.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
  $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h
 iter_resptype.lo iter_resptype.o: $(srcdir)/iterator/iter_resptype.c config.h \
  $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
  $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h
 iter_scrub.lo iter_scrub.o: $(srcdir)/iterator/iter_scrub.c config.h $(srcdir)/iterator/iter_scrub.h \
  $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_priv.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/util/alloc.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/iterator/iter_priv.h $(srcdir)/util/rbtree.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/util/alloc.h $(srcdir)/sldns/sbuffer.h
 iter_utils.lo iter_utils.o: $(srcdir)/iterator/iter_utils.c config.h $(srcdir)/iterator/iter_utils.h \
  $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_hints.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h \
  $(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_priv.h \
  $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
+  $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
  $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/str2wire.h
+ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/sldns/str2wire.h
 listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h \
  $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
-  $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/sbuffer.h
+  $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
+  $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h \
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h
 localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
  $(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/as112.h
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/as112.h
 mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/services/modstack.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/edns.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/data/dname.h $(srcdir)/respip/respip.h
+ $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/services/listen_dnsport.h
 modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
  $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/respip/respip.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(PYTHONMOD_HEADER) \
- $(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h \
- $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h
 view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h
+rpz.lo rpz.o: $(srcdir)/services/rpz.c config.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \
+ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
 outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
  $(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
  
 outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c config.h \
  $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h  \
+ $(srcdir)/dnscrypt/dnscrypt.h   \
  $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
- 
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h \
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
+ $(srcdir)/dnstap/dnstap.h
 alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h
+ $(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
 config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/util/log.h \
  $(srcdir)/util/configyyrename.h $(srcdir)/util/config_file.h util/configparser.h \
  $(srcdir)/util/net_help.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/util/rtt.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/wire2str.h \
- $(srcdir)/sldns/parseutil.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/iana_ports.inc
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/util/iana_ports.inc
 configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
  $(srcdir)/util/config_file.h util/configparser.h
 configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
@@ -828,159 +860,163 @@
  $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
 shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
  $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
-   $(srcdir)/daemon/worker.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
- $(srcdir)/dnstap/dnstap.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rtt.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h
+ $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+  $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/services/mesh.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/rtt.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/tube.h
 authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/services/authzone.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/data/msgparse.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/random.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/services/outside_network.h  \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_secalgo.h
+ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h  \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_nsec3.h \
+ $(srcdir)/validator/val_secalgo.h
 fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/outside_network.h  $(srcdir)/services/localzone.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/validator/validator.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
- $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
- $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
- $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h \
- $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h \
- $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h $(srcdir)/edns-subnet/addrtree.h \
- $(srcdir)/edns-subnet/edns-subnet.h
-locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h
-log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/outside_network.h  $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
+ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.h \
+ $(srcdir)/libunbound/worker.h
+locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
+log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
 mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h
+  $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
 module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
 netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
+  $(srcdir)/util/ub_event.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h \
  $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
  $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/dnstap/dnstap.h \
-  \
- 
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/dnstap/dnstap.h  $(srcdir)/services/listen_dnsport.h
 net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
- 
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
 random.lo random.o: $(srcdir)/util/random.c config.h $(srcdir)/util/random.h $(srcdir)/util/log.h
 rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
 regional.lo regional.o: $(srcdir)/util/regional.c config.h $(srcdir)/util/log.h $(srcdir)/util/regional.h
 rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h $(srcdir)/iterator/iterator.h \
  $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
-edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/config_file.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/regional.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
+edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h
 dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h
+ $(srcdir)/util/log.h $(srcdir)/util/net_help.h
 lookup3.lo lookup3.o: $(srcdir)/util/storage/lookup3.c config.h $(srcdir)/util/storage/lookup3.h
 lruhash.lo lruhash.o: $(srcdir)/util/storage/lruhash.c config.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
 slabhash.lo slabhash.o: $(srcdir)/util/storage/slabhash.c config.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
 tcp_conn_limit.lo tcp_conn_limit.o: $(srcdir)/util/tcp_conn_limit.c config.h $(srcdir)/util/regional.h \
  $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/tcp_conn_limit.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
 timehist.lo timehist.o: $(srcdir)/util/timehist.c config.h $(srcdir)/util/timehist.h $(srcdir)/util/log.h
 tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
- $(srcdir)/util/ub_event.h
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h
 ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/tube.h \
- $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
+ $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
 ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \
  $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
- $(srcdir)/util/rbtree.h
+  $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
 winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h
 autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/validator/autotrust.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_sigcrypt.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/services/modstack.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/keyraw.h \
- 
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/services/mesh.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h
 val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/autotrust.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/validator/autotrust.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/as112.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h \
  $(srcdir)/sldns/str2wire.h
 validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/validator/validator.h \
  $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
  $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_kcache.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_nsec.h \
  $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_sigcrypt.h \
@@ -987,22 +1023,22 @@
  $(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
  $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/modstack.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+  $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
 val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h
+ $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
 val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h \
- $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
- 
-val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h
+val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h \
  $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
@@ -1009,157 +1045,105 @@
  $(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
 val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/validator/val_secalgo.h \
- $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
- $(srcdir)/validator/val_kentry.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/validator/val_nsec.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/validator/val_nsec.h $(srcdir)/sldns/sbuffer.h
 val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/validator/val_nsec.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h
+ $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h
 val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/sbuffer.h \
- 
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
+ $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/sldns/sbuffer.h
 val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \
  $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
- 
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \
+ $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/sldns/wire2str.h
 val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/parseutil.h
 dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
-edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h \
- $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
-subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h $(srcdir)/edns-subnet/subnetmod.h \
- $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
- $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/services/modstack.h \
- $(srcdir)/services/cache/dns.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
+edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h
+subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h
 addrtree.lo addrtree.o: $(srcdir)/edns-subnet/addrtree.c config.h $(srcdir)/util/log.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h
-subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h \
- $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
- $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h
-cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/cachedb/redis.h $(srcdir)/util/regional.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h \
- $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h \
- $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
-redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h $(srcdir)/cachedb/cachedb.h \
- $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h
+subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h
+cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h
+redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h
 respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/respip/respip.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/services/modstack.h \
+ $(srcdir)/services/rpz.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/regional.h
 checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
  $(srcdir)/testcode/checklocks.h
-dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/lookup3.h
-ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h $(srcdir)/ipsecmod/ipsecmod.h \
- $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h \
- $(srcdir)/ipsecmod/ipsecmod-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
- $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/sldns/wire2str.h
-ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h \
- $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
+ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h
+ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h
 unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/rrdef.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \
+ $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h
 unitdname.lo unitdname.o: $(srcdir)/testcode/unitdname.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
 unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \
- $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/storage/slabhash.h
-unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h \
- $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/random.h $(srcdir)/respip/respip.h $(srcdir)/services/localzone.h \
- $(srcdir)/services/view.h
+ $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
+unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/random.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h
 unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
  $(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
- $(srcdir)/testcode/readhex.h $(srcdir)/testcode/testpkts.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/testcode/readhex.h \
+ $(srcdir)/testcode/testpkts.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
 unitneg.lo unitneg.o: $(srcdir)/testcode/unitneg.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/dname.h $(srcdir)/testcode/unitmain.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h
+ $(srcdir)/util/data/dname.h $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/sldns/rrdef.h
 unitregional.lo unitregional.o: $(srcdir)/testcode/unitregional.c config.h $(srcdir)/testcode/unitmain.h \
  $(srcdir)/util/log.h $(srcdir)/util/regional.h
 unitslabhash.lo unitslabhash.o: $(srcdir)/testcode/unitslabhash.c config.h $(srcdir)/testcode/unitmain.h \
- $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h
+ $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h
 unitverify.lo unitverify.o: $(srcdir)/testcode/unitverify.c config.h $(srcdir)/util/log.h \
  $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_nsec3.h \
  $(srcdir)/util/rbtree.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
@@ -1173,31 +1157,27 @@
  $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
 unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
  $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
-unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h $(srcdir)/edns-subnet/addrtree.h \
- $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/services/outbound_list.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/edns-subnet.h
+unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h
 unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/data/msgparse.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
- $(srcdir)/testcode/unitmain.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/testcode/unitmain.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/wire2str.h
 acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
-cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \
- $(srcdir)/daemon/cachedump.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
+ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
+cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
  $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
  $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  \
@@ -1207,27 +1187,24 @@
  $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h \
  $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
  $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
-daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
   $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
  $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
  $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
- $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h \
- $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
-remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \
+ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
+ $(srcdir)/sldns/keyraw.h
+remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
+ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/alloc.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
  $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
  $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
@@ -1234,68 +1211,71 @@
  $(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \
  $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
- $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
- $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
- $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
+ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/sldns/wire2str.h
 stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
  $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  \
+ $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/tube.h \
+ $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
  $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
- $(srcdir)/validator/val_neg.h
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
 unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
-   $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
- $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
+ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+  $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/ub_event.h
 worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
- $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
+ $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
  $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
 testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
  $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/daemon/daemon.h \
- $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
+  $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c \
+ $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+  $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
 testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
  $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
@@ -1302,196 +1282,199 @@
 worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
- $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \
- $(srcdir)/respip/respip.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
+ $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
+ $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
  $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
 acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
-daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
+daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
   $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
  $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
  $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
- $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h \
- $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \
+ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
+ $(srcdir)/sldns/keyraw.h
 stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
  $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/alloc.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h \
- $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  \
+ $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/tube.h \
+ $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
  $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
- $(srcdir)/validator/val_neg.h
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
 replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
+  $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
  $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
 fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/testcode/fake_event.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
  $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
  $(srcdir)/util/rbtree.h  $(srcdir)/services/cache/infra.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h \
  $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
 lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
+ $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
 pktview.lo pktview.o: $(srcdir)/testcode/pktview.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h \
- $(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h $(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/sldns/parseutil.h
 readhex.lo readhex.o: $(srcdir)/testcode/readhex.c config.h $(srcdir)/testcode/readhex.h $(srcdir)/util/log.h \
  $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
 memstats.lo memstats.o: $(srcdir)/testcode/memstats.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
+ $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
 unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c config.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/regional.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
- $(srcdir)/iterator/iter_fwd.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
- $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
+ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h $(srcdir)/sldns/sbuffer.h \
- $(PYTHONMOD_HEADER) $(srcdir)/edns-subnet/subnet-whitelist.h
+ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
 worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
+ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
 context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbound/context.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \
+ $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
 libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
  $(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/libunbound/libworker.h $(srcdir)/util/config_file.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h \
- $(srcdir)/util/ub_event.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/services/view.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/dnscrypt/cert.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h \
- $(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.h
-libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
- $(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/libunbound/context.h \
- $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h  \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \
+ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
+libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h   \
  $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/services/authzone.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
+ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \
  $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/sldns/str2wire.h
 unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \
- 
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
 asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
- $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h \
- 
+ $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
 streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
- 
-perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
 delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
-unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h \
- $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/pkthdr.h
+unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h
 unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h \
- 
-petal.lo petal.o: $(srcdir)/testcode/petal.c config.h \
- 
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
+petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
 pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
- $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/regional.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
- 
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+  $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
+ $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h
 win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
-  $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
- $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h
+ $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+   $(srcdir)/daemon/worker.h \
+ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h \
+ $(srcdir)/util/net_help.h
 w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
 unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
  $(srcdir)/winrc/w_inst.h
@@ -1499,14 +1482,12 @@
  $(srcdir)/winrc/w_inst.h
 anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h
-keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/rrdef.h \
- 
+keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/rrdef.h
 sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h
 wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/keyraw.h \
- 
+ $(srcdir)/sldns/keyraw.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h
 parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \
  $(srcdir)/sldns/sbuffer.h
 parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h
@@ -1513,8 +1494,7 @@
 rrdef.lo rrdef.o: $(srcdir)/sldns/rrdef.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
 str2wire.lo str2wire.o: $(srcdir)/sldns/str2wire.c config.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
  $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h
-ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h
+ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
 fake-rfc2553.lo fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h
 gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c config.h
 inet_aton.lo inet_aton.o: $(srcdir)/compat/inet_aton.c config.h
@@ -1527,11 +1507,10 @@
 strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
 strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
 strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
-getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h \
- 
-getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
-getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h \
- 
+getentropy_freebsd.lo getentropy_freebsd.o: $(srcdir)/compat/getentropy_freebsd.c
+getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
+getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c
+getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
 getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
 explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
 arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h
--- contrib/unbound/README.md.orig
+++ contrib/unbound/README.md
@@ -0,0 +1,38 @@
+# Unbound
+
+[![Travis Build Status](https://travis-ci.org/NLnetLabs/unbound.svg?branch=master)](https://travis-ci.org/NLnetLabs/unbound)
+[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
+[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
+
+Unbound is a validating, recursive, caching DNS resolver. It is designed to be
+fast and lean and incorporates modern features based on open standards. If you
+have any feedback, we would love to hear from you. Don’t hesitate to
+[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
+or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
+You can lean more about Unbound by reading our
+[documentation](https://nlnetlabs.nl/documentation/unbound/).
+
+## Compiling
+
+Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
+installed. Unbound can be compiled and installed using:
+
+```
+./configure && make && make install
+```
+
+You can use libevent if you want. libevent is useful when using many (10000)
+outgoing ports. By default max 256 ports are opened at the same time and the
+builtin alternative is equally capable and a little faster.
+
+Use the `--with-libevent=dir` configure option to compile Unbound with libevent
+support.
+
+## Unbound configuration
+
+All of Unbound's configuration options are described in the man pages, which
+will be installed and are available on the Unbound
+[documentation page](https://nlnetlabs.nl/documentation/unbound/).
+
+An example configuration file is located in
+[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
--- contrib/unbound/aclocal.m4.orig
+++ contrib/unbound/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9390,7 +9390,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9421,7 +9421,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 2006-2017 Free Software Foundation, Inc.
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
--- contrib/unbound/cachedb/cachedb.c.orig
+++ contrib/unbound/cachedb/cachedb.c
@@ -64,14 +64,27 @@
 #ifdef HAVE_SYS_ENDIAN_H
 #  include <sys/endian.h>
 #endif
-#ifdef HAVE_LIBKERN_OSBYTEORDER_H
-/* In practice this is specific to MacOS X.  We assume it doesn't have
-* htobe64/be64toh but has alternatives with a different name. */
-#  include <libkern/OSByteOrder.h>
-#  define htobe64(x) OSSwapHostToBigInt64(x)
-#  define be64toh(x) OSSwapBigToHostInt64(x)
-#endif
 
+#ifndef HAVE_HTOBE64
+#  ifdef HAVE_LIBKERN_OSBYTEORDER_H
+     /* In practice this is specific to MacOS X.  We assume it doesn't have
+      * htobe64/be64toh but has alternatives with a different name. */
+#    include <libkern/OSByteOrder.h>
+#    define htobe64(x) OSSwapHostToBigInt64(x)
+#    define be64toh(x) OSSwapBigToHostInt64(x)
+#  else
+     /* not OSX */
+     /* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */
+#    if __BIG_ENDIAN__
+#      define be64toh(n) (n)
+#      define htobe64(n) (n)
+#    else
+#      define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
+#      define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
+#    endif /* _ENDIAN */
+#  endif /* HAVE_LIBKERN_OSBYTEORDER_H */
+#endif /* HAVE_BE64TOH */
+
 /** the unit test testframe for cachedb, its module state contains
  * a cache for a couple queries (in memory). */
 struct testframe_moddata {
@@ -205,10 +218,6 @@
 cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
 {
 	const char* backend_str = cfg->cachedb_backend;
-
-	/* If unspecified we use the in-memory test DB. */
-	if(!backend_str)
-		backend_str = "testframe";
 	cachedb_env->backend = cachedb_find_backend(backend_str);
 	if(!cachedb_env->backend) {
 		log_err("cachedb: cannot find backend name '%s'", backend_str);
@@ -231,6 +240,8 @@
 	env->modinfo[id] = (void*)cachedb_env;
 	if(!cachedb_apply_cfg(cachedb_env, env->cfg)) {
 		log_err("cachedb: could not apply configuration settings.");
+		free(cachedb_env);
+		env->modinfo[id] = NULL;
 		return 0;
 	}
 	/* see if a backend is selected */
@@ -239,9 +250,20 @@
 	if(!(*cachedb_env->backend->init)(env, cachedb_env)) {
 		log_err("cachedb: could not init %s backend",
 			cachedb_env->backend->name);
+		free(cachedb_env);
+		env->modinfo[id] = NULL;
 		return 0;
 	}
 	cachedb_env->enabled = 1;
+	if(env->cfg->serve_expired_reply_ttl)
+		log_warn(
+			"cachedb: serve-expired-reply-ttl is set but not working for data "
+			"originating from the external cache; 0 TLL is used for those.");
+	if(env->cfg->serve_expired_client_timeout)
+		log_warn(
+			"cachedb: serve-expired-client-timeout is set but not working for "
+			"data originating from the external cache; expired data are used "
+			"in the reply without first trying to refresh the data.");
 	return 1;
 }
 
@@ -312,8 +334,7 @@
 	size_t clen = 0;
 	uint8_t hash[CACHEDB_HASHSIZE/8];
 	const char* hex = "0123456789ABCDEF";
-	const char* secret = qstate->env->cfg->cachedb_secret ?
-		qstate->env->cfg->cachedb_secret : "default";
+	const char* secret = qstate->env->cfg->cachedb_secret;
 	size_t i;
 
 	/* copy the hash info into the clear buffer */
@@ -336,7 +357,11 @@
 	
 	/* hash the buffer */
 	secalgo_hash_sha256(clear, clen, hash);
+#ifdef HAVE_EXPLICIT_BZERO
+	explicit_bzero(clear, clen);
+#else
 	memset(clear, 0, clen);
+#endif
 
 	/* hex encode output for portability (some online dbs need
 	 * no nulls, no control characters, and so on) */
@@ -412,8 +437,14 @@
 		&expiry, sizeof(expiry));
 	expiry = be64toh(expiry);
 
+	/* Check if we are allowed to return expired entries:
+	 * - serve_expired needs to be set
+	 * - if SERVE_EXPIRED_TTL is set make sure that the record is not older
+	 *   than that. */
 	if((time_t)expiry < *qstate->env->now &&
-		!qstate->env->cfg->serve_expired)
+		(!qstate->env->cfg->serve_expired ||
+			(SERVE_EXPIRED_TTL &&
+			*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
 		return 0;
 
 	return 1;
@@ -424,15 +455,15 @@
 static void
 packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
 {
-        size_t i;
-        size_t total = data->count + data->rrsig_count;
+	size_t i;
+	size_t total = data->count + data->rrsig_count;
 	if(subtract >= 0 && data->ttl > subtract)
 		data->ttl -= subtract;
 	else	data->ttl = 0;
-        for(i=0; i<total; i++) {
+	for(i=0; i<total; i++) {
 		if(subtract >= 0 && data->rr_ttl[i] > subtract)
-                	data->rr_ttl[i] -= subtract;
-                else	data->rr_ttl[i] = 0;
+			data->rr_ttl[i] -= subtract;
+		else	data->rr_ttl[i] = 0;
 	}
 }
 
@@ -444,7 +475,8 @@
 	size_t i;
 	if(adjust >= 0 && msg->rep->ttl > adjust)
 		msg->rep->ttl -= adjust;
-	else	msg->rep->ttl = 0;
+	else
+		msg->rep->ttl = 0;
 	msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
 	msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
 
@@ -652,7 +684,8 @@
 		return;
 	}
 
-	/* lookup inside unbound's internal cache */
+	/* lookup inside unbound's internal cache.
+	 * This does not look for expired entries. */
 	if(cachedb_intcache_lookup(qstate)) {
 		if(verbosity >= VERB_ALGO) {
 			if(qstate->return_msg->rep)
@@ -660,8 +693,9 @@
 					&qstate->return_msg->qinfo,
 					qstate->return_msg->rep);
 			else log_info("cachedb internal cache lookup: rcode %s",
-				sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)?
-				sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name:"??");
+				sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)
+				?sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name
+				:"??");
 		}
 		/* we are done with the query */
 		qstate->ext_state[id] = module_finished;
@@ -676,6 +710,19 @@
 				qstate->return_msg->rep);
 		/* store this result in internal cache */
 		cachedb_intcache_store(qstate);
+		/* In case we have expired data but there is a client timer for expired
+		 * answers, pass execution to next module in order to try updating the
+		 * data first.
+		 * TODO: this needs revisit. The expired data stored from cachedb has
+		 * 0 TTL which is picked up by iterator later when looking in the cache.
+		 * Document that ext cachedb does not work properly with
+		 * serve_stale_reply_ttl yet. */
+		if(qstate->need_refetch && qstate->serve_expired_data &&
+			qstate->serve_expired_data->timer) {
+				qstate->return_msg = NULL;
+				qstate->ext_state[id] = module_wait_module;
+				return;
+		}
 		/* we are done with the query */
 		qstate->ext_state[id] = module_finished;
 		return;
--- contrib/unbound/compat/arc4random.c.orig
+++ contrib/unbound/compat/arc4random.c
@@ -140,6 +140,7 @@
 static inline void
 _rs_init(u_char *buf, size_t n)
 {
+	assert(buf);
 	if (n < KEYSZ + IVSZ)
 		return;
 
--- contrib/unbound/compat/getentropy_freebsd.c.orig
+++ contrib/unbound/compat/getentropy_freebsd.c
@@ -0,0 +1,62 @@
+/*	$OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $	*/
+
+/*
+ * Copyright (c) 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * Copyright (c) 2014 Brent Cook <bcook@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://man.openbsd.org/getentropy.2
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <errno.h>
+#include <stddef.h>
+
+/*
+ * Derived from lib/libc/gen/arc4random.c from FreeBSD.
+ */
+static size_t
+getentropy_sysctl(u_char *buf, size_t size)
+{
+	int mib[2];
+	size_t len, done;
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_ARND;
+	done = 0;
+
+	do {
+		len = size;
+		if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
+			return (done);
+		done += len;
+		buf += len;
+		size -= len;
+	} while (size > 0);
+
+	return (done);
+}
+
+int
+getentropy(void *buf, size_t len)
+{
+	if (len <= 256 && getentropy_sysctl(buf, len) == len)
+		return (0);
+
+	errno = EIO;
+	return (-1);
+}
--- contrib/unbound/compat/getentropy_linux.c.orig
+++ contrib/unbound/compat/getentropy_linux.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $	*/
+/*	$OpenBSD: getentropy_linux.c,v 1.46 2018/11/20 08:04:28 deraadt Exp $	*/
 
 /*
  * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -15,12 +15,15 @@
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://man.openbsd.org/getentropy.2
  */
+
 #include "config.h"
-
 /*
-#define	_POSIX_C_SOURCE 199309L
-#define	_GNU_SOURCE     1
+#define	_POSIX_C_SOURCE	199309L
+#define	_GNU_SOURCE	1
 */
 #include <sys/types.h>
 #include <sys/param.h>
@@ -27,8 +30,8 @@
 #include <sys/ioctl.h>
 #include <sys/resource.h>
 #include <sys/syscall.h>
-#ifdef HAVE_SYS_SYSCTL_H
-#include <sys/sysctl.h>
+#ifdef SYS__sysctl
+#include <linux/sysctl.h>
 #endif
 #include <sys/statvfs.h>
 #include <sys/socket.h>
@@ -39,6 +42,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <link.h>
 #include <termios.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -46,16 +50,18 @@
 #include <errno.h>
 #include <unistd.h>
 #include <time.h>
-
-#if defined(HAVE_SSL)
+#ifndef HAVE_NETTLE
 #include <openssl/sha.h>
-#elif defined(HAVE_NETTLE)
+#else
 #include <nettle/sha.h>
+#define SHA512_CTX		struct sha512_ctx
+#define SHA512_Init(x)		sha512_init(x)
+#define SHA512_Update(x, b, s)	sha512_update(x, s, b)
+#define SHA512_Final(r, c)	sha512_digest(c, SHA512_DIGEST_SIZE, r)
 #endif
 
 #include <linux/types.h>
 #include <linux/random.h>
-#include <linux/sysctl.h>
 #ifdef HAVE_GETAUXVAL
 #include <sys/auxv.h>
 #endif
@@ -75,29 +81,13 @@
 			HD(b); \
 	} while (0)
 
-#if defined(HAVE_SSL)
-#define CRYPTO_SHA512_CTX		SHA512_CTX
-#define CRYPTO_SHA512_INIT(x)		SHA512_Init(x)
-#define CRYPTO_SHA512_FINAL(r, c)	SHA512_Final(r, c)
 #define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
 #define HD(x)	 (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
 #define HF(x)    (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
-#elif defined(HAVE_NETTLE)
-#define CRYPTO_SHA512_CTX		struct sha512_ctx
-#define CRYPTO_SHA512_INIT(x)		sha512_init(x)
-#define CRYPTO_SHA512_FINAL(r, c)	sha512_digest(c, SHA512_DIGEST_SIZE, r)
-#define HR(x, l) (sha512_update(&ctx, (l), (uint8_t *)(x)))
-#define HD(x)	 (sha512_update(&ctx, sizeof (x), (uint8_t *)&(x)))
-#define HF(x)    (sha512_update(&ctx, sizeof (void*), (uint8_t *)&(x)))
-#endif
 
 int	getentropy(void *buf, size_t len);
 
-#ifdef CAN_REFERENCE_MAIN
-extern int main(int, char *argv[]);
-#endif
-static int gotdata(char *buf, size_t len);
-#if defined(SYS_getrandom) && defined(__NR_getrandom)
+#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
 static int getentropy_getrandom(void *buf, size_t len);
 #endif
 static int getentropy_urandom(void *buf, size_t len);
@@ -105,6 +95,7 @@
 static int getentropy_sysctl(void *buf, size_t len);
 #endif
 static int getentropy_fallback(void *buf, size_t len);
+static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
 
 int
 getentropy(void *buf, size_t len)
@@ -113,18 +104,21 @@
 
 	if (len > 256) {
 		errno = EIO;
-		return -1;
+		return (-1);
 	}
 
-#if defined(SYS_getrandom) && defined(__NR_getrandom)
+#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
 	/*
-	 * Try descriptor-less getrandom()
+	 * Try descriptor-less getrandom(), in non-blocking mode.
+	 *
+	 * The design of Linux getrandom is broken.  It has an
+	 * uninitialized phase coupled with blocking behaviour, which
+	 * is unacceptable from within a library at boot time without
+	 * possible recovery. See http://bugs.python.org/issue26839#msg267745
 	 */
 	ret = getentropy_getrandom(buf, len);
 	if (ret != -1)
 		return (ret);
-	if (errno != ENOSYS)
-		return (-1);
 #endif
 
 	/*
@@ -178,7 +172,7 @@
 	 *     - Do the best under the circumstances....
 	 *
 	 * This code path exists to bring light to the issue that Linux
-	 * does not provide a failsafe API for entropy collection.
+	 * still does not provide a failsafe API for entropy collection.
 	 *
 	 * We hope this demonstrates that Linux should either retain their
 	 * sysctl ABI, or consider providing a new failsafe API which
@@ -196,24 +190,8 @@
 	return (ret);
 }
 
-/*
- * Basic sanity checking; wish we could do better.
- */
+#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
 static int
-gotdata(char *buf, size_t len)
-{
-	char	any_set = 0;
-	size_t	i;
-
-	for (i = 0; i < len; ++i)
-		any_set |= buf[i];
-	if (any_set == 0)
-		return -1;
-	return 0;
-}
-
-#if defined(SYS_getrandom) && defined(__NR_getrandom)
-static int
 getentropy_getrandom(void *buf, size_t len)
 {
 	int pre_errno = errno;
@@ -221,7 +199,7 @@
 	if (len > 256)
 		return (-1);
 	do {
-		ret = syscall(SYS_getrandom, buf, len, 0);
+		ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
 	} while (ret == -1 && errno == EINTR);
 
 	if (ret != (int)len)
@@ -269,7 +247,7 @@
 	}
 	for (i = 0; i < len; ) {
 		size_t wanted = len - i;
-		ssize_t ret = read(fd, (char*)buf + i, wanted);
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
 
 		if (ret == -1) {
 			if (errno == EAGAIN || errno == EINTR)
@@ -280,13 +258,11 @@
 		i += ret;
 	}
 	close(fd);
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return 0;		/* satisfied */
-	}
+	errno = save_errno;
+	return (0);		/* satisfied */
 nodevrandom:
 	errno = EIO;
-	return -1;
+	return (-1);
 }
 
 #ifdef SYS__sysctl
@@ -311,17 +287,15 @@
 			goto sysctlfailed;
 		i += chunk;
 	}
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return (0);			/* satisfied */
-	}
+	errno = save_errno;
+	return (0);			/* satisfied */
 sysctlfailed:
 	errno = EIO;
-	return -1;
+	return (-1);
 }
 #endif /* SYS__sysctl */
 
-static int cl[] = {
+static const int cl[] = {
 	CLOCK_REALTIME,
 #ifdef CLOCK_MONOTONIC
 	CLOCK_MONOTONIC,
@@ -347,6 +321,15 @@
 };
 
 static int
+getentropy_phdr(struct dl_phdr_info *info, size_t ATTR_UNUSED(size), void *data)
+{
+	SHA512_CTX *ctx = data;
+
+	SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
+	return (0);
+}
+
+static int
 getentropy_fallback(void *buf, size_t len)
 {
 	uint8_t results[SHA512_DIGEST_LENGTH];
@@ -357,7 +340,7 @@
 	struct rusage ru;
 	sigset_t sigset;
 	struct stat st;
-	CRYPTO_SHA512_CTX ctx;
+	SHA512_CTX ctx;
 	static pid_t lastpid;
 	pid_t pid;
 	size_t i, ii, m;
@@ -374,7 +357,7 @@
 	}
 	for (i = 0; i < len; ) {
 		int j;
-		CRYPTO_SHA512_INIT(&ctx);
+		SHA512_Init(&ctx);
 		for (j = 0; j < repeat; j++) {
 			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
 			if (e != -1) {
@@ -382,6 +365,8 @@
 				cnt += (int)tv.tv_usec;
 			}
 
+			dl_iterate_phdr(getentropy_phdr, &ctx);
+
 			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
 				HX(clock_gettime(cl[ii], &ts) == -1, ts);
 
@@ -401,9 +386,6 @@
 			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
 			    sigset);
 
-#ifdef CAN_REFERENCE_MAIN
-			HF(main);		/* an addr in program */
-#endif
 			HF(getentropy);	/* an addr in this library */
 			HF(printf);		/* an addr in libc */
 			p = (char *)&p;
@@ -528,33 +510,30 @@
 			HD(cnt);
 		}
 #ifdef HAVE_GETAUXVAL
-#  ifdef AT_RANDOM
+#ifdef AT_RANDOM
 		/* Not as random as you think but we take what we are given */
 		p = (char *) getauxval(AT_RANDOM);
 		if (p)
 			HR(p, 16);
-#  endif
-#  ifdef AT_SYSINFO_EHDR
+#endif
+#ifdef AT_SYSINFO_EHDR
 		p = (char *) getauxval(AT_SYSINFO_EHDR);
 		if (p)
 			HR(p, pgs);
-#  endif
-#  ifdef AT_BASE
+#endif
+#ifdef AT_BASE
 		p = (char *) getauxval(AT_BASE);
 		if (p)
 			HD(p);
-#  endif
-#endif /* HAVE_GETAUXVAL */
+#endif
+#endif
 
-		CRYPTO_SHA512_FINAL(results, &ctx);
-		memcpy((char*)buf + i, results, min(sizeof(results), len - i));
+		SHA512_Final(results, &ctx);
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
 		i += min(sizeof(results), len - i);
 	}
-	memset(results, 0, sizeof results);
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return 0;		/* satisfied */
-	}
-	errno = EIO;
-	return -1;
+	explicit_bzero(&ctx, sizeof ctx);
+	explicit_bzero(results, sizeof results);
+	errno = save_errno;
+	return (0);		/* satisfied */
 }
--- contrib/unbound/compat/getentropy_osx.c.orig
+++ contrib/unbound/compat/getentropy_osx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 deraadt Exp $	*/
+/*	$OpenBSD: getentropy_osx.c,v 1.12 2018/11/20 08:04:28 deraadt Exp $	*/
 
 /*
  * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -15,9 +15,12 @@
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://man.openbsd.org/getentropy.2
  */
-#include "config.h"
 
+#include <TargetConditionals.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -43,14 +46,18 @@
 #include <mach/mach_time.h>
 #include <mach/mach_host.h>
 #include <mach/host_info.h>
+#if TARGET_OS_OSX
 #include <sys/socketvar.h>
 #include <sys/vmmeter.h>
+#endif
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+#if TARGET_OS_OSX
 #include <netinet/udp.h>
 #include <netinet/ip_var.h>
 #include <netinet/tcp_var.h>
 #include <netinet/udp_var.h>
+#endif
 #include <CommonCrypto/CommonDigest.h>
 #define SHA512_Update(a, b, c)	(CC_SHA512_Update((a), (b), (c)))
 #define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
@@ -75,10 +82,6 @@
 
 int	getentropy(void *buf, size_t len);
 
-#ifdef CAN_REFERENCE_MAIN
-extern int main(int, char *argv[]);
-#endif
-static int gotdata(char *buf, size_t len);
 static int getentropy_urandom(void *buf, size_t len);
 static int getentropy_fallback(void *buf, size_t len);
 
@@ -89,7 +92,7 @@
 
 	if (len > 256) {
 		errno = EIO;
-		return -1;
+		return (-1);
 	}
 
 	/*
@@ -138,23 +141,7 @@
 	return (ret);
 }
 
-/*
- * Basic sanity checking; wish we could do better.
- */
 static int
-gotdata(char *buf, size_t len)
-{
-	char	any_set = 0;
-	size_t	i;
-
-	for (i = 0; i < len; ++i)
-		any_set |= buf[i];
-	if (any_set == 0)
-		return -1;
-	return 0;
-}
-
-static int
 getentropy_urandom(void *buf, size_t len)
 {
 	struct stat st;
@@ -188,7 +175,7 @@
 	}
 	for (i = 0; i < len; ) {
 		size_t wanted = len - i;
-		ssize_t ret = read(fd, (char*)buf + i, wanted);
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
 
 		if (ret == -1) {
 			if (errno == EAGAIN || errno == EINTR)
@@ -199,18 +186,18 @@
 		i += ret;
 	}
 	close(fd);
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return 0;		/* satisfied */
-	}
+	errno = save_errno;
+	return (0);		/* satisfied */
 nodevrandom:
 	errno = EIO;
-	return -1;
+	return (-1);
 }
 
+#if TARGET_OS_OSX
 static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
 static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
 static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
+#endif
 static int kmib[] = { CTL_KERN, KERN_USRSTACK };
 static int hwmib[] = { CTL_HW, HW_USERMEM };
 
@@ -230,9 +217,11 @@
 	pid_t pid;
 	size_t i, ii, m;
 	char *p;
+#if TARGET_OS_OSX
 	struct tcpstat tcpstat;
 	struct udpstat udpstat;
 	struct ipstat ipstat;
+#endif
 	u_int64_t mach_time;
 	unsigned int idata;
 	void *addr;
@@ -267,6 +256,7 @@
 			HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
 			    &idata, &ii, NULL, 0) == -1, idata);
 
+#if TARGET_OS_OSX
 			ii = sizeof(tcpstat);
 			HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
 			    &tcpstat, &ii, NULL, 0) == -1, tcpstat);
@@ -278,6 +268,7 @@
 			ii = sizeof(ipstat);
 			HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
 			    &ipstat, &ii, NULL, 0) == -1, ipstat);
+#endif
 
 			HX((pid = getpid()) == -1, pid);
 			HX((pid = getsid(pid)) == -1, pid);
@@ -295,9 +286,6 @@
 			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
 			    sigset);
 
-#ifdef CAN_REFERENCE_MAIN
-			HF(main);		/* an addr in program */
-#endif
 			HF(getentropy);	/* an addr in this library */
 			HF(printf);		/* an addr in libc */
 			p = (char *)&p;
@@ -419,14 +407,11 @@
 		}
 
 		SHA512_Final(results, &ctx);
-		memcpy((char*)buf + i, results, min(sizeof(results), len - i));
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
 		i += min(sizeof(results), len - i);
 	}
-	memset(results, 0, sizeof results);
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return 0;		/* satisfied */
-	}
-	errno = EIO;
-	return -1;
+	explicit_bzero(&ctx, sizeof ctx);
+	explicit_bzero(results, sizeof results);
+	errno = save_errno;
+	return (0);		/* satisfied */
 }
--- contrib/unbound/compat/getentropy_solaris.c.orig
+++ contrib/unbound/compat/getentropy_solaris.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 deraadt Exp $	*/
+/*	$OpenBSD: getentropy_solaris.c,v 1.4 2014/07/12 20:41:47 wouter Exp $	*/
 
 /*
  * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -204,7 +204,7 @@
 	}
 	for (i = 0; i < len; ) {
 		size_t wanted = len - i;
-		ssize_t ret = read(fd, (char*)buf + i, wanted);
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
 
 		if (ret == -1) {
 			if (errno == EAGAIN || errno == EINTR)
@@ -428,7 +428,7 @@
 			HD(cnt);
 		}
 		SHA512_Final(results, &ctx);
-		memcpy((char*)buf + i, results, min(sizeof(results), len - i));
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
 		i += min(sizeof(results), len - i);
 	}
 	memset(results, 0, sizeof results);
--- contrib/unbound/compat/getentropy_win.c.orig
+++ contrib/unbound/compat/getentropy_win.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD$	*/
+/*	$OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $	*/
 
 /*
  * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org> 
@@ -15,6 +15,9 @@
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://man.openbsd.org/getentropy.2
  */
 
 #include <windows.h>
@@ -37,7 +40,7 @@
 
 	if (len > 256) {
 		errno = EIO;
-		return -1;
+		return (-1);
 	}
 
 	if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
--- contrib/unbound/compat/malloc.c.orig
+++ contrib/unbound/compat/malloc.c
@@ -5,7 +5,12 @@
 #undef malloc
 #include <sys/types.h>
 
+#ifndef USE_WINSOCK
 void *malloc ();
+#else
+/* provide a prototype */
+void *malloc (size_t n);
+#endif
 
 /* Allocate an N-byte block of memory from the heap.
    If N is zero, allocate a 1-byte block.  */
--- contrib/unbound/compat/snprintf.c.orig
+++ contrib/unbound/compat/snprintf.c
@@ -658,7 +658,7 @@
 		 * are not their own functions. */
 
 		/* printout designation:
-		 * conversion specifier: x, d, u, s, c, n, m, p
+		 * conversion specifier: x, d, u, s, c, m, p
 		 * flags: # not supported
 		 *        0 zeropad (on the left)
 		 *	  - left adjust (right by default)
@@ -798,7 +798,10 @@
 				minw, minus);
 			break;
 		case 'n':
-			*va_arg(arg, int*) = ret;
+			/* unsupported to harden against format string
+			 * exploitation,
+			 * handled like an unknown format specifier. */
+			/* *va_arg(arg, int*) = ret; */
 			break;
 		case 'm':
 			print_str(&at, &left, &ret, strerror(errno),
--- contrib/unbound/config.guess.orig
+++ contrib/unbound/config.guess
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/usr/bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2016 Free Software Foundation, Inc.
 
--- contrib/unbound/config.h.orig
+++ contrib/unbound/config.h
@@ -1,1279 +0,0 @@
-/* config.h.  Generated from config.h.in by configure.  */
-/* config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* apply the noreturn attribute to a function that exits the program */
-#define ATTR_NORETURN __attribute__((__noreturn__))
-
-/* apply the weak attribute to a symbol */
-#define ATTR_WEAK __attribute__((weak))
-
-/* Directory to chroot to */
-#define CHROOT_DIR "/var/unbound"
-
-/* Define this to enable client subnet option. */
-/* #undef CLIENT_SUBNET */
-
-/* Do sha512 definitions in config.h */
-/* #undef COMPAT_SHA512 */
-
-/* Pathname to the Unbound configuration file */
-#define CONFIGFILE "/var/unbound/unbound.conf"
-
-/* Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work
-   */
-/* #undef DARWIN_BROKEN_SETREUID */
-
-/* Whether daemon is deprecated */
-/* #undef DEPRECATED_DAEMON */
-
-/* default dnstap socket path */
-/* #undef DNSTAP_SOCKET_PATH */
-
-/* Define if you want to use debug lock checking (slow). */
-/* #undef ENABLE_LOCK_CHECKS */
-
-/* Define this if you enabled-allsymbols from libunbound to link binaries to
-   it for smaller install size, but the libunbound export table is polluted by
-   internal symbols */
-/* #undef EXPORT_ALL_SYMBOLS */
-
-/* Define to 1 if you have the `accept4' function. */
-#define HAVE_ACCEPT4 1
-
-/* Define to 1 if you have the `arc4random' function. */
-#define HAVE_ARC4RANDOM 1
-
-/* Define to 1 if you have the `arc4random_uniform' function. */
-#define HAVE_ARC4RANDOM_UNIFORM 1
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Whether the C compiler accepts the "format" attribute */
-#define HAVE_ATTR_FORMAT 1
-
-/* Whether the C compiler accepts the "noreturn" attribute */
-#define HAVE_ATTR_NORETURN 1
-
-/* Whether the C compiler accepts the "unused" attribute */
-#define HAVE_ATTR_UNUSED 1
-
-/* Whether the C compiler accepts the "weak" attribute */
-#define HAVE_ATTR_WEAK 1
-
-/* Define to 1 if you have the `chown' function. */
-#define HAVE_CHOWN 1
-
-/* Define to 1 if you have the `chroot' function. */
-#define HAVE_CHROOT 1
-
-/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
-/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */
-
-/* Define to 1 if you have the `ctime_r' function. */
-#define HAVE_CTIME_R 1
-
-/* Define to 1 if you have the `daemon' function. */
-#define HAVE_DAEMON 1
-
-/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_ARC4RANDOM */
-
-/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0
-   if you don't. */
-/* #undef HAVE_DECL_ARC4RANDOM_UNIFORM */
-
-/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
-   don't. */
-#define HAVE_DECL_INET_NTOP 1
-
-/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you
-   don't. */
-#define HAVE_DECL_INET_PTON 1
-
-/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
-   don't. */
-#define HAVE_DECL_NID_ED25519 1
-
-/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
-   don't. */
-#define HAVE_DECL_NID_ED448 1
-
-/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
-   don't. */
-#define HAVE_DECL_NID_SECP384R1 1
-
-/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0
-   if you don't. */
-#define HAVE_DECL_NID_X9_62_PRIME256V1 1
-
-/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_REALLOCARRAY */
-
-/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_REDISCONNECT */
-
-/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
-   if you don't. */
-#define HAVE_DECL_SK_SSL_COMP_POP_FREE 1
-
-/* Define to 1 if you have the declaration of
-   `SSL_COMP_get_compression_methods', and to 0 if you don't. */
-#define HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS 1
-
-/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to
-   0 if you don't. */
-#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO 1
-
-/* Define to 1 if you have the declaration of `strlcat', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_STRLCAT */
-
-/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you
-   don't. */
-/* #undef HAVE_DECL_STRLCPY */
-
-/* Define to 1 if you have the declaration of `XML_StopParser', and to 0 if
-   you don't. */
-#define HAVE_DECL_XML_STOPPARSER 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `DSA_SIG_set0' function. */
-#define HAVE_DSA_SIG_SET0 1
-
-/* Define to 1 if you have the <endian.h> header file. */
-/* #undef HAVE_ENDIAN_H */
-
-/* Define to 1 if you have the `endprotoent' function. */
-#define HAVE_ENDPROTOENT 1
-
-/* Define to 1 if you have the `endpwent' function. */
-#define HAVE_ENDPWENT 1
-
-/* Define to 1 if you have the `endservent' function. */
-#define HAVE_ENDSERVENT 1
-
-/* Define to 1 if you have the `ERR_free_strings' function. */
-/* #undef HAVE_ERR_FREE_STRINGS */
-
-/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
-/* #undef HAVE_ERR_LOAD_CRYPTO_STRINGS */
-
-/* Define to 1 if you have the `event_base_free' function. */
-/* #undef HAVE_EVENT_BASE_FREE */
-
-/* Define to 1 if you have the `event_base_get_method' function. */
-/* #undef HAVE_EVENT_BASE_GET_METHOD */
-
-/* Define to 1 if you have the `event_base_new' function. */
-/* #undef HAVE_EVENT_BASE_NEW */
-
-/* Define to 1 if you have the `event_base_once' function. */
-/* #undef HAVE_EVENT_BASE_ONCE */
-
-/* Define to 1 if you have the <event.h> header file. */
-/* #undef HAVE_EVENT_H */
-
-/* Define to 1 if you have the `EVP_cleanup' function. */
-/* #undef HAVE_EVP_CLEANUP */
-
-/* Define to 1 if you have the `EVP_DigestVerify' function. */
-#define HAVE_EVP_DIGESTVERIFY 1
-
-/* Define to 1 if you have the `EVP_dss1' function. */
-/* #undef HAVE_EVP_DSS1 */
-
-/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
-#define HAVE_EVP_MD_CTX_NEW 1
-
-/* Define to 1 if you have the `EVP_sha1' function. */
-#define HAVE_EVP_SHA1 1
-
-/* Define to 1 if you have the `EVP_sha256' function. */
-#define HAVE_EVP_SHA256 1
-
-/* Define to 1 if you have the `EVP_sha512' function. */
-#define HAVE_EVP_SHA512 1
-
-/* Define to 1 if you have the `ev_default_loop' function. */
-/* #undef HAVE_EV_DEFAULT_LOOP */
-
-/* Define to 1 if you have the `ev_loop' function. */
-/* #undef HAVE_EV_LOOP */
-
-/* Define to 1 if you have the <expat.h> header file. */
-#define HAVE_EXPAT_H 1
-
-/* Define to 1 if you have the `explicit_bzero' function. */
-#define HAVE_EXPLICIT_BZERO 1
-
-/* Define to 1 if you have the `fcntl' function. */
-#define HAVE_FCNTL 1
-
-/* Define to 1 if you have the `FIPS_mode' function. */
-#define HAVE_FIPS_MODE 1
-
-/* Define to 1 if you have the `fork' function. */
-#define HAVE_FORK 1
-
-/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
-#define HAVE_FSEEKO 1
-
-/* Define to 1 if you have the `fsync' function. */
-#define HAVE_FSYNC 1
-
-/* Whether getaddrinfo is available */
-#define HAVE_GETADDRINFO 1
-
-/* Define to 1 if you have the `getauxval' function. */
-/* #undef HAVE_GETAUXVAL */
-
-/* Define to 1 if you have the `getentropy' function. */
-/* #undef HAVE_GETENTROPY */
-
-/* Define to 1 if you have the <getopt.h> header file. */
-#define HAVE_GETOPT_H 1
-
-/* Define to 1 if you have the `getpwnam' function. */
-#define HAVE_GETPWNAM 1
-
-/* Define to 1 if you have the `getrlimit' function. */
-#define HAVE_GETRLIMIT 1
-
-/* Define to 1 if you have the `glob' function. */
-#define HAVE_GLOB 1
-
-/* Define to 1 if you have the <glob.h> header file. */
-#define HAVE_GLOB_H 1
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#define HAVE_GMTIME_R 1
-
-/* Define to 1 if you have the <grp.h> header file. */
-#define HAVE_GRP_H 1
-
-/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
-/* #undef HAVE_HIREDIS_HIREDIS_H */
-
-/* If you have HMAC_Update */
-#define HAVE_HMAC_UPDATE 1
-
-/* Define to 1 if you have the `inet_aton' function. */
-#define HAVE_INET_ATON 1
-
-/* Define to 1 if you have the `inet_ntop' function. */
-#define HAVE_INET_NTOP 1
-
-/* Define to 1 if you have the `inet_pton' function. */
-#define HAVE_INET_PTON 1
-
-/* Define to 1 if you have the `initgroups' function. */
-#define HAVE_INITGROUPS 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* if the function 'ioctlsocket' is available */
-/* #undef HAVE_IOCTLSOCKET */
-
-/* Define to 1 if you have the <iphlpapi.h> header file. */
-/* #undef HAVE_IPHLPAPI_H */
-
-/* Define to 1 if you have the `isblank' function. */
-#define HAVE_ISBLANK 1
-
-/* Define to 1 if you have the `kill' function. */
-#define HAVE_KILL 1
-
-/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
-/* #undef HAVE_LIBKERN_OSBYTEORDER_H */
-
-/* Define if we have LibreSSL */
-/* #undef HAVE_LIBRESSL */
-
-/* Define to 1 if you have the `localtime_r' function. */
-#define HAVE_LOCALTIME_R 1
-
-/* Define to 1 if you have the <login_cap.h> header file. */
-#define HAVE_LOGIN_CAP_H 1
-
-/* If have GNU libc compatible malloc */
-#define HAVE_MALLOC 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-#define HAVE_NETINET_TCP_H 1
-
-/* Use libnettle for crypto */
-/* #undef HAVE_NETTLE */
-
-/* Define to 1 if you have the <nettle/dsa-compat.h> header file. */
-/* #undef HAVE_NETTLE_DSA_COMPAT_H */
-
-/* Define to 1 if you have the <nettle/eddsa.h> header file. */
-/* #undef HAVE_NETTLE_EDDSA_H */
-
-/* Use libnss for crypto */
-/* #undef HAVE_NSS */
-
-/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */
-/* #undef HAVE_OPENSSL_ADD_ALL_DIGESTS */
-
-/* Define to 1 if you have the <openssl/bn.h> header file. */
-#define HAVE_OPENSSL_BN_H 1
-
-/* Define to 1 if you have the `OPENSSL_config' function. */
-#define HAVE_OPENSSL_CONFIG 1
-
-/* Define to 1 if you have the <openssl/conf.h> header file. */
-#define HAVE_OPENSSL_CONF_H 1
-
-/* Define to 1 if you have the <openssl/dh.h> header file. */
-#define HAVE_OPENSSL_DH_H 1
-
-/* Define to 1 if you have the <openssl/dsa.h> header file. */
-#define HAVE_OPENSSL_DSA_H 1
-
-/* Define to 1 if you have the <openssl/engine.h> header file. */
-#define HAVE_OPENSSL_ENGINE_H 1
-
-/* Define to 1 if you have the <openssl/err.h> header file. */
-#define HAVE_OPENSSL_ERR_H 1
-
-/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
-#define HAVE_OPENSSL_INIT_CRYPTO 1
-
-/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
-#define HAVE_OPENSSL_INIT_SSL 1
-
-/* Define to 1 if you have the <openssl/rand.h> header file. */
-#define HAVE_OPENSSL_RAND_H 1
-
-/* Define to 1 if you have the <openssl/rsa.h> header file. */
-#define HAVE_OPENSSL_RSA_H 1
-
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-#define HAVE_OPENSSL_SSL_H 1
-
-/* Define if you have POSIX threads libraries and header files. */
-#define HAVE_PTHREAD 1
-
-/* Have PTHREAD_PRIO_INHERIT. */
-#define HAVE_PTHREAD_PRIO_INHERIT 1
-
-/* Define to 1 if the system has the type `pthread_rwlock_t'. */
-#define HAVE_PTHREAD_RWLOCK_T 1
-
-/* Define to 1 if the system has the type `pthread_spinlock_t'. */
-#define HAVE_PTHREAD_SPINLOCK_T 1
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#define HAVE_PWD_H 1
-
-/* Define if you have Python libraries and header files. */
-/* #undef HAVE_PYTHON */
-
-/* Define to 1 if you have the `random' function. */
-#define HAVE_RANDOM 1
-
-/* Define to 1 if you have the `RAND_cleanup' function. */
-/* #undef HAVE_RAND_CLEANUP */
-
-/* Define to 1 if you have the `reallocarray' function. */
-#define HAVE_REALLOCARRAY 1
-
-/* Define to 1 if you have the `recvmsg' function. */
-#define HAVE_RECVMSG 1
-
-/* Define to 1 if you have the `sendmsg' function. */
-#define HAVE_SENDMSG 1
-
-/* Define to 1 if you have the `setregid' function. */
-/* #undef HAVE_SETREGID */
-
-/* Define to 1 if you have the `setresgid' function. */
-#define HAVE_SETRESGID 1
-
-/* Define to 1 if you have the `setresuid' function. */
-#define HAVE_SETRESUID 1
-
-/* Define to 1 if you have the `setreuid' function. */
-/* #undef HAVE_SETREUID */
-
-/* Define to 1 if you have the `setrlimit' function. */
-#define HAVE_SETRLIMIT 1
-
-/* Define to 1 if you have the `setsid' function. */
-#define HAVE_SETSID 1
-
-/* Define to 1 if you have the `setusercontext' function. */
-#define HAVE_SETUSERCONTEXT 1
-
-/* Define to 1 if you have the `SHA512_Update' function. */
-/* #undef HAVE_SHA512_UPDATE */
-
-/* Define to 1 if you have the `shmget' function. */
-#define HAVE_SHMGET 1
-
-/* Define to 1 if you have the `sigprocmask' function. */
-#define HAVE_SIGPROCMASK 1
-
-/* Define to 1 if you have the `sleep' function. */
-#define HAVE_SLEEP 1
-
-/* Define to 1 if you have the `snprintf' function. */
-#define HAVE_SNPRINTF 1
-
-/* Define to 1 if you have the `socketpair' function. */
-#define HAVE_SOCKETPAIR 1
-
-/* Using Solaris threads */
-/* #undef HAVE_SOLARIS_THREADS */
-
-/* Define to 1 if you have the `srandom' function. */
-#define HAVE_SRANDOM 1
-
-/* Define if you have the SSL libraries installed. */
-#define HAVE_SSL /**/
-
-/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
-#define HAVE_SSL_CTX_SET_SECURITY_LEVEL 1
-
-/* Define to 1 if you have the `SSL_get0_peername' function. */
-#define HAVE_SSL_GET0_PEERNAME 1
-
-/* Define to 1 if you have the `SSL_set1_host' function. */
-#define HAVE_SSL_SET1_HOST 1
-
-/* Define to 1 if you have the <stdarg.h> header file. */
-#define HAVE_STDARG_H 1
-
-/* Define to 1 if you have the <stdbool.h> header file. */
-#define HAVE_STDBOOL_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strftime' function. */
-#define HAVE_STRFTIME 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strlcat' function. */
-#define HAVE_STRLCAT 1
-
-/* Define to 1 if you have the `strlcpy' function. */
-#define HAVE_STRLCPY 1
-
-/* Define to 1 if you have the `strptime' function. */
-#define HAVE_STRPTIME 1
-
-/* Define to 1 if you have the `strsep' function. */
-#define HAVE_STRSEP 1
-
-/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
-/* #undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST */
-
-/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
-#define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1
-
-/* Define if you have Swig libraries and header files. */
-/* #undef HAVE_SWIG */
-
-/* Define to 1 if you have the <syslog.h> header file. */
-#define HAVE_SYSLOG_H 1
-
-/* Define to 1 if systemd should be used */
-/* #undef HAVE_SYSTEMD */
-
-/* Define to 1 if you have the <sys/endian.h> header file. */
-#define HAVE_SYS_ENDIAN_H 1
-
-/* Define to 1 if you have the <sys/ipc.h> header file. */
-#define HAVE_SYS_IPC_H 1
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#define HAVE_SYS_RESOURCE_H 1
-
-/* Define to 1 if you have the <sys/sha2.h> header file. */
-/* #undef HAVE_SYS_SHA2_H */
-
-/* Define to 1 if you have the <sys/shm.h> header file. */
-#define HAVE_SYS_SHM_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/sysctl.h> header file. */
-/* #undef HAVE_SYS_SYSCTL_H */
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/uio.h> header file. */
-#define HAVE_SYS_UIO_H 1
-
-/* Define to 1 if you have the <sys/un.h> header file. */
-#define HAVE_SYS_UN_H 1
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the `tzset' function. */
-#define HAVE_TZSET 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `usleep' function. */
-#define HAVE_USLEEP 1
-
-/* Define to 1 if you have the `vfork' function. */
-#define HAVE_VFORK 1
-
-/* Define to 1 if you have the <vfork.h> header file. */
-/* #undef HAVE_VFORK_H */
-
-/* Define to 1 if you have the <windows.h> header file. */
-/* #undef HAVE_WINDOWS_H */
-
-/* Using Windows threads */
-/* #undef HAVE_WINDOWS_THREADS */
-
-/* Define to 1 if you have the <winsock2.h> header file. */
-/* #undef HAVE_WINSOCK2_H */
-
-/* Define to 1 if `fork' works. */
-#define HAVE_WORKING_FORK 1
-
-/* Define to 1 if `vfork' works. */
-#define HAVE_WORKING_VFORK 1
-
-/* Define to 1 if you have the `writev' function. */
-#define HAVE_WRITEV 1
-
-/* Define to 1 if you have the <ws2tcpip.h> header file. */
-/* #undef HAVE_WS2TCPIP_H */
-
-/* Define to 1 if you have the `_beginthreadex' function. */
-/* #undef HAVE__BEGINTHREADEX */
-
-/* if lex has yylex_destroy */
-#define LEX_HAS_YYLEX_DESTROY 1
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* Define to the maximum message length to pass to syslog. */
-#define MAXSYSLOGMSGLEN 10240
-
-/* Define if memcmp() does not compare unsigned bytes */
-/* #undef MEMCMP_IS_BROKEN */
-
-/* Define if mkdir has one argument. */
-/* #undef MKDIR_HAS_ONE_ARG */
-
-/* Define if the network stack does not fully support nonblocking io (causes
-   lower performance). */
-/* #undef NONBLOCKING_IS_BROKEN */
-
-/* Put -D_ALL_SOURCE define in config.h */
-/* #undef OMITTED__D_ALL_SOURCE */
-
-/* Put -D_BSD_SOURCE define in config.h */
-/* #undef OMITTED__D_BSD_SOURCE */
-
-/* Put -D_DEFAULT_SOURCE define in config.h */
-/* #undef OMITTED__D_DEFAULT_SOURCE */
-
-/* Put -D_GNU_SOURCE define in config.h */
-/* #undef OMITTED__D_GNU_SOURCE */
-
-/* Put -D_LARGEFILE_SOURCE=1 define in config.h */
-/* #undef OMITTED__D_LARGEFILE_SOURCE_1 */
-
-/* Put -D_POSIX_C_SOURCE=200112 define in config.h */
-/* #undef OMITTED__D_POSIX_C_SOURCE_200112 */
-
-/* Put -D_XOPEN_SOURCE=600 define in config.h */
-/* #undef OMITTED__D_XOPEN_SOURCE_600 */
-
-/* Put -D_XOPEN_SOURCE_EXTENDED=1 define in config.h */
-/* #undef OMITTED__D_XOPEN_SOURCE_EXTENDED_1 */
-
-/* Put -D__EXTENSIONS__ define in config.h */
-/* #undef OMITTED__D__EXTENSIONS__ */
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "unbound-bugs@nlnetlabs.nl"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "unbound"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "unbound 1.8.1"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "unbound"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.8.1"
-
-/* default pidfile location */
-#define PIDFILE "/var/unbound/unbound.pid"
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#define RETSIGTYPE void
-
-/* if REUSEPORT is enabled by default */
-#define REUSEPORT_DEFAULT 0
-
-/* default rootkey location */
-#define ROOT_ANCHOR_FILE "/var/unbound/root.key"
-
-/* default rootcert location */
-#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem"
-
-/* version number for resource files */
-#define RSRC_PACKAGE_VERSION 1,8,1,0
-
-/* Directory to chdir to */
-#define RUN_DIR "/var/unbound"
-
-/* Shared data */
-#define SHARE_DIR "/var/unbound"
-
-/* The size of `time_t', as computed by sizeof. */
-#define SIZEOF_TIME_T 8
-
-/* define if (v)snprintf does not return length needed, (but length used) */
-/* #undef SNPRINTF_RET_BROKEN */
-
-/* Define to 1 if libsodium supports sodium_set_misuse_handler */
-/* #undef SODIUM_MISUSE_HANDLER */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* use default strptime. */
-#define STRPTIME_WORKS 1
-
-/* Use win32 resources and API */
-/* #undef UB_ON_WINDOWS */
-
-/* default username */
-#define UB_USERNAME "unbound"
-
-/* use to enable lightweight alloc assertions, for debug use */
-/* #undef UNBOUND_ALLOC_LITE */
-
-/* use malloc not regions, for debug use */
-/* #undef UNBOUND_ALLOC_NONREGIONAL */
-
-/* use statistics for allocs and frees, for debug use */
-/* #undef UNBOUND_ALLOC_STATS */
-
-/* define this to enable debug checks. */
-/* #undef UNBOUND_DEBUG */
-
-/* Define to 1 to use cachedb support */
-/* #undef USE_CACHEDB */
-
-/* Define to 1 to enable dnscrypt support */
-/* #undef USE_DNSCRYPT */
-
-/* Define to 1 to enable dnscrypt with xchacha20 support */
-/* #undef USE_DNSCRYPT_XCHACHA20 */
-
-/* Define to 1 to enable dnstap support */
-/* #undef USE_DNSTAP */
-
-/* Define this to enable DSA support. */
-#define USE_DSA 1
-
-/* Define this to enable ECDSA support. */
-#define USE_ECDSA 1
-
-/* Define this to enable an EVP workaround for older openssl */
-/* #undef USE_ECDSA_EVP_WORKAROUND */
-
-/* Define this to enable ED25519 support. */
-#define USE_ED25519 1
-
-/* Define this to enable ED448 support. */
-#define USE_ED448 1
-
-/* Define this to enable GOST support. */
-/* #undef USE_GOST */
-
-/* Define to 1 to use ipsecmod support. */
-/* #undef USE_IPSECMOD */
-
-/* Define if you want to use internal select based events */
-#define USE_MINI_EVENT 1
-
-/* Define this to enable client TCP Fast Open. */
-/* #undef USE_MSG_FASTOPEN */
-
-/* Define this to enable client TCP Fast Open. */
-/* #undef USE_OSX_MSG_FASTOPEN */
-
-/* Define this to use hiredis client. */
-/* #undef USE_REDIS */
-
-/* Define this to enable SHA1 support. */
-#define USE_SHA1 1
-
-/* Define this to enable SHA256 and SHA512 support. */
-#define USE_SHA2 1
-
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them.  */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Define this to enable server TCP Fast Open. */
-/* #undef USE_TCP_FASTOPEN */
-
-/* Whether the windows socket API is used */
-/* #undef USE_WINSOCK */
-
-/* the version of the windows API enabled */
-#define WINVER 0x0502
-
-/* Define if you want Python module. */
-/* #undef WITH_PYTHONMODULE */
-
-/* Define if you want PyUnbound. */
-/* #undef WITH_PYUNBOUND */
-
-/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
-   `char[]'. */
-#define YYTEXT_POINTER 1
-
-/* Enable large inode numbers on Mac OS X 10.5.  */
-#ifndef _DARWIN_USE_64_BIT_INODE
-# define _DARWIN_USE_64_BIT_INODE 1
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
-/* #undef _LARGEFILE_SOURCE */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Enable for compile on Minix */
-/* #undef _NETBSD_SOURCE */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef gid_t */
-
-/* in_addr_t */
-/* #undef in_addr_t */
-
-/* in_port_t */
-/* #undef in_port_t */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to `short' if <sys/types.h> does not define. */
-/* #undef int16_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef int32_t */
-
-/* Define to `long long' if <sys/types.h> does not define. */
-/* #undef int64_t */
-
-/* Define to `signed char' if <sys/types.h> does not define. */
-/* #undef int8_t */
-
-/* Define if replacement function should be used. */
-/* #undef malloc */
-
-/* Define to `long int' if <sys/types.h> does not define. */
-/* #undef off_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef pid_t */
-
-/* Define to 'int' if not defined */
-/* #undef rlim_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define to 'int' if not defined */
-/* #undef socklen_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef ssize_t */
-
-/* Define to 'unsigned char if not defined */
-/* #undef u_char */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef uid_t */
-
-/* Define to `unsigned short' if <sys/types.h> does not define. */
-/* #undef uint16_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef uint32_t */
-
-/* Define to `unsigned long long' if <sys/types.h> does not define. */
-/* #undef uint64_t */
-
-/* Define to `unsigned char' if <sys/types.h> does not define. */
-/* #undef uint8_t */
-
-/* Define as `fork' if `vfork' does not work. */
-/* #undef vfork */
-
-#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE)
-#define _GNU_SOURCE 1
-#endif 
-
-#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE)
-#define _BSD_SOURCE 1
-#endif 
-
-#if defined(OMITTED__D_DEFAULT_SOURCE) && !defined(_DEFAULT_SOURCE)
-#define _DEFAULT_SOURCE 1
-#endif 
-
-#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__)
-#define __EXTENSIONS__ 1
-#endif 
-
-#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 200112
-#endif 
-
-#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE)
-#define _XOPEN_SOURCE 600
-#endif 
-
-#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED)
-#define _XOPEN_SOURCE_EXTENDED 1
-#endif 
-
-#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE)
-#define _ALL_SOURCE 1
-#endif 
-
-#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE)
-#define _LARGEFILE_SOURCE 1
-#endif 
-
-
-
-
-#ifndef UNBOUND_DEBUG
-#  define NDEBUG
-#endif
-
-/** Use small-ldns codebase */
-#define USE_SLDNS 1
-#ifdef HAVE_SSL
-#  define LDNS_BUILD_CONFIG_HAVE_SSL 1
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-
-#ifdef HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#include <errno.h>
-
-#if HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_SYS_UIO_H
-#include <sys/uio.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_NETINET_TCP_H
-#include <netinet/tcp.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-
-#ifdef HAVE_WS2TCPIP_H
-#include <ws2tcpip.h>
-#endif
-
-#ifndef USE_WINSOCK
-#define ARG_LL "%ll"
-#else
-#define ARG_LL "%I64"
-#endif
-
-#ifndef AF_LOCAL
-#define AF_LOCAL AF_UNIX
-#endif
-
-
- 
-#ifdef HAVE_ATTR_FORMAT
-#  define ATTR_FORMAT(archetype, string_index, first_to_check) \
-    __attribute__ ((format (archetype, string_index, first_to_check)))
-#else /* !HAVE_ATTR_FORMAT */
-#  define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
-#endif /* !HAVE_ATTR_FORMAT */
-
-
-#if defined(DOXYGEN)
-#  define ATTR_UNUSED(x)  x
-#elif defined(__cplusplus)
-#  define ATTR_UNUSED(x)
-#elif defined(HAVE_ATTR_UNUSED)
-#  define ATTR_UNUSED(x)  x __attribute__((unused))
-#else /* !HAVE_ATTR_UNUSED */
-#  define ATTR_UNUSED(x)  x
-#endif /* !HAVE_ATTR_UNUSED */
-
-
-#ifndef HAVE_FSEEKO
-#define fseeko fseek
-#define ftello ftell
-#endif /* HAVE_FSEEKO */
-
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
-
-#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
-#define snprintf snprintf_unbound
-#define vsnprintf vsnprintf_unbound
-#include <stdarg.h>
-int snprintf (char *str, size_t count, const char *fmt, ...);
-int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-#endif /* HAVE_SNPRINTF or SNPRINTF_RET_BROKEN */
-
-#ifndef HAVE_INET_PTON
-#define inet_pton inet_pton_unbound
-int inet_pton(int af, const char* src, void* dst);
-#endif /* HAVE_INET_PTON */
-
-
-#ifndef HAVE_INET_NTOP
-#define inet_ntop inet_ntop_unbound
-const char *inet_ntop(int af, const void *src, char *dst, size_t size);
-#endif
-
-
-#ifndef HAVE_INET_ATON
-#define inet_aton inet_aton_unbound
-int inet_aton(const char *cp, struct in_addr *addr);
-#endif
-
-
-#ifndef HAVE_MEMMOVE
-#define memmove memmove_unbound
-void *memmove(void *dest, const void *src, size_t n);
-#endif
-
-
-#ifndef HAVE_STRLCAT
-#define strlcat strlcat_unbound
-size_t strlcat(char *dst, const char *src, size_t siz);
-#endif
-
-
-#ifndef HAVE_STRLCPY
-#define strlcpy strlcpy_unbound
-size_t strlcpy(char *dst, const char *src, size_t siz);
-#endif
-
-
-#ifndef HAVE_GMTIME_R
-#define gmtime_r gmtime_r_unbound
-struct tm *gmtime_r(const time_t *timep, struct tm *result);
-#endif
-
-
-#ifndef HAVE_REALLOCARRAY
-#define reallocarray reallocarrayunbound
-void* reallocarray(void *ptr, size_t nmemb, size_t size);
-#endif
-
-
-#if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H)
-#define sleep(x) Sleep((x)*1000) /* on win32 */
-#endif /* HAVE_SLEEP */
-
-
-#ifndef HAVE_USLEEP
-#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */
-#endif /* HAVE_USLEEP */
-
-
-#ifndef HAVE_RANDOM
-#define random rand /* on win32, for tests only (bad random) */
-#endif /* HAVE_RANDOM */
-
-
-#ifndef HAVE_SRANDOM
-#define srandom(x) srand(x) /* on win32, for tests only (bad random) */
-#endif /* HAVE_SRANDOM */
-
-
-/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
-#ifdef HAVE_WINSOCK2_H
-#define FD_SET_T (u_int)
-#else
-#define FD_SET_T 
-#endif
-
-
-#ifndef IPV6_MIN_MTU
-#define IPV6_MIN_MTU 1280
-#endif /* IPV6_MIN_MTU */
-
-
-#ifdef MEMCMP_IS_BROKEN
-#include "compat/memcmp.h"
-#define memcmp memcmp_unbound
-int memcmp(const void *x, const void *y, size_t n);
-#endif
-
-
-
-#ifndef HAVE_CTIME_R
-#define ctime_r unbound_ctime_r
-char *ctime_r(const time_t *timep, char *buf);
-#endif
-
-#ifndef HAVE_STRSEP
-#define strsep unbound_strsep
-char *strsep(char **stringp, const char *delim);
-#endif
-
-#ifndef HAVE_ISBLANK
-#define isblank unbound_isblank
-int isblank(int c);
-#endif
-
-#ifndef HAVE_EXPLICIT_BZERO
-#define explicit_bzero unbound_explicit_bzero
-void explicit_bzero(void* buf, size_t len);
-#endif
-
-#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
-const char *inet_ntop(int af, const void *src, char *dst, size_t size);
-#endif
-
-#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
-int inet_pton(int af, const char* src, void* dst);
-#endif
-
-#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
-#define strptime unbound_strptime
-struct tm;
-char *strptime(const char *s, const char *format, struct tm *tm);
-#endif
-
-#ifdef HAVE_LIBRESSL
-#  if !HAVE_DECL_STRLCPY
-size_t strlcpy(char *dst, const char *src, size_t siz);
-#  endif
-#  if !HAVE_DECL_STRLCAT
-size_t strlcat(char *dst, const char *src, size_t siz);
-#  endif
-#  if !HAVE_DECL_ARC4RANDOM && defined(HAVE_ARC4RANDOM)
-uint32_t arc4random(void);
-#  endif
-#  if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
-uint32_t arc4random_uniform(uint32_t upper_bound);
-#  endif
-#  if !HAVE_DECL_REALLOCARRAY
-void *reallocarray(void *ptr, size_t nmemb, size_t size);
-#  endif
-#endif /* HAVE_LIBRESSL */
-#ifndef HAVE_ARC4RANDOM
-int getentropy(void* buf, size_t len);
-uint32_t arc4random(void);
-void arc4random_buf(void* buf, size_t n);
-void _ARC4_LOCK(void);
-void _ARC4_UNLOCK(void);
-void _ARC4_LOCK_DESTROY(void);
-#endif
-#ifndef HAVE_ARC4RANDOM_UNIFORM
-uint32_t arc4random_uniform(uint32_t upper_bound);
-#endif
-#ifdef COMPAT_SHA512
-#ifndef SHA512_DIGEST_LENGTH
-#define SHA512_BLOCK_LENGTH		128
-#define SHA512_DIGEST_LENGTH		64
-#define SHA512_DIGEST_STRING_LENGTH	(SHA512_DIGEST_LENGTH * 2 + 1)
-typedef struct _SHA512_CTX {
-	uint64_t	state[8];
-	uint64_t	bitcount[2];
-	uint8_t	buffer[SHA512_BLOCK_LENGTH];
-} SHA512_CTX;
-#endif /* SHA512_DIGEST_LENGTH */
-void SHA512_Init(SHA512_CTX*);
-void SHA512_Update(SHA512_CTX*, void*, size_t);
-void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
-unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest);
-#endif /* COMPAT_SHA512 */
-
-
-
-#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
-   /* using version of libevent that is not threadsafe. */
-#  define LIBEVENT_SIGNAL_PROBLEM 1
-#endif
-
-#ifndef CHECKED_INET6
-#  define CHECKED_INET6
-#  ifdef AF_INET6
-#    define INET6
-#  else
-#    define AF_INET6        28
-#  endif
-#endif /* CHECKED_INET6 */
-
-#ifndef HAVE_GETADDRINFO
-struct sockaddr_storage;
-#include "compat/fake-rfc2553.h"
-#endif
-
-#ifdef UNBOUND_ALLOC_STATS
-#  define malloc(s) unbound_stat_malloc_log(s, __FILE__, __LINE__, __func__)
-#  define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
-#  define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
-#  define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
-void *unbound_stat_malloc(size_t size);
-void *unbound_stat_calloc(size_t nmemb, size_t size);
-void unbound_stat_free(void *ptr);
-void *unbound_stat_realloc(void *ptr, size_t size);
-void *unbound_stat_malloc_log(size_t size, const char* file, int line,
-	const char* func);
-void *unbound_stat_calloc_log(size_t nmemb, size_t size, const char* file,
-	int line, const char* func);
-void unbound_stat_free_log(void *ptr, const char* file, int line,
-	const char* func);
-void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
-	int line, const char* func);
-#elif defined(UNBOUND_ALLOC_LITE)
-#  include "util/alloc.h"
-#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
-
-/** default port for DNS traffic. */
-#define UNBOUND_DNS_PORT 53
-/** default port for DNS over TLS traffic. */
-#define UNBOUND_DNS_OVER_TLS_PORT 853
-/** default port for unbound control traffic, registered port with IANA,
-    ub-dns-control  8953/tcp    unbound dns nameserver control */
-#define UNBOUND_CONTROL_PORT 8953
-/** the version of unbound-control that this software implements */
-#define UNBOUND_CONTROL_VERSION 1
-
-
--- contrib/unbound/config.h.in.orig
+++ contrib/unbound/config.h.in
@@ -15,6 +15,9 @@
 /* Do sha512 definitions in config.h */
 #undef COMPAT_SHA512
 
+/* Command line arguments used with configure */
+#undef CONFCMDLINE
+
 /* Pathname to the Unbound configuration file */
 #undef CONFIGFILE
 
@@ -60,6 +63,15 @@
 /* Whether the C compiler accepts the "weak" attribute */
 #undef HAVE_ATTR_WEAK
 
+/* If we have be64toh */
+#undef HAVE_BE64TOH
+
+/* Define to 1 if you have the <bsd/stdlib.h> header file. */
+#undef HAVE_BSD_STDLIB_H
+
+/* Define to 1 if you have the <bsd/string.h> header file. */
+#undef HAVE_BSD_STRING_H
+
 /* Define to 1 if you have the `chown' function. */
 #undef HAVE_CHOWN
 
@@ -69,6 +81,9 @@
 /* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
 #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
 
+/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
+#undef HAVE_CRYPTO_THREADID_SET_CALLBACK
+
 /* Define to 1 if you have the `ctime_r' function. */
 #undef HAVE_CTIME_R
 
@@ -83,6 +98,10 @@
    if you don't. */
 #undef HAVE_DECL_ARC4RANDOM_UNIFORM
 
+/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if
+   you don't. */
+#undef HAVE_DECL_EVSIGNAL_ASSIGN
+
 /* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
    don't. */
 #undef HAVE_DECL_INET_NTOP
@@ -163,6 +182,9 @@
 /* Define to 1 if you have the `ERR_load_crypto_strings' function. */
 #undef HAVE_ERR_LOAD_CRYPTO_STRINGS
 
+/* Define to 1 if you have the `event_assign' function. */
+#undef HAVE_EVENT_ASSIGN
+
 /* Define to 1 if you have the `event_base_free' function. */
 #undef HAVE_EVENT_BASE_FREE
 
@@ -178,6 +200,9 @@
 /* Define to 1 if you have the <event.h> header file. */
 #undef HAVE_EVENT_H
 
+/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
+#undef HAVE_EVP_AES_256_CBC
+
 /* Define to 1 if you have the `EVP_cleanup' function. */
 #undef HAVE_EVP_CLEANUP
 
@@ -187,6 +212,9 @@
 /* Define to 1 if you have the `EVP_dss1' function. */
 #undef HAVE_EVP_DSS1
 
+/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
+#undef HAVE_EVP_ENCRYPTINIT_EX
+
 /* Define to 1 if you have the `EVP_MD_CTX_new' function. */
 #undef HAVE_EVP_MD_CTX_NEW
 
@@ -259,9 +287,15 @@
 /* Define to 1 if you have the <hiredis/hiredis.h> header file. */
 #undef HAVE_HIREDIS_HIREDIS_H
 
+/* Define to 1 if you have the `HMAC_Init_ex' function. */
+#undef HAVE_HMAC_INIT_EX
+
 /* If you have HMAC_Update */
 #undef HAVE_HMAC_UPDATE
 
+/* If we have htobe64 */
+#undef HAVE_HTOBE64
+
 /* Define to 1 if you have the `inet_aton' function. */
 #undef HAVE_INET_ATON
 
@@ -289,6 +323,9 @@
 /* Define to 1 if you have the `kill' function. */
 #undef HAVE_KILL
 
+/* Use portable libbsd functions */
+#undef HAVE_LIBBSD
+
 /* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
 #undef HAVE_LIBKERN_OSBYTEORDER_H
 
@@ -394,7 +431,7 @@
 /* Define to 1 if you have the `RAND_cleanup' function. */
 #undef HAVE_RAND_CLEANUP
 
-/* Define to 1 if you have the `reallocarray' function. */
+/* If we have reallocarray(3) */
 #undef HAVE_REALLOCARRAY
 
 /* Define to 1 if you have the `recvmsg' function. */
@@ -451,9 +488,15 @@
 /* Define if you have the SSL libraries installed. */
 #undef HAVE_SSL
 
+/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
+#undef HAVE_SSL_CTX_SET_CIPHERSUITES
+
 /* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
 #undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
 
+/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
+#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB
+
 /* Define to 1 if you have the `SSL_get0_peername' function. */
 #undef HAVE_SSL_GET0_PEERNAME
 
@@ -586,9 +629,15 @@
 /* Define to 1 if you have the <ws2tcpip.h> header file. */
 #undef HAVE_WS2TCPIP_H
 
+/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
+#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
+
 /* Define to 1 if you have the `_beginthreadex' function. */
 #undef HAVE__BEGINTHREADEX
 
+/* If HMAC_Init_ex() returns void */
+#undef HMAC_INIT_EX_RETURNS_VOID
+
 /* if lex has yylex_destroy */
 #undef LEX_HAS_YYLEX_DESTROY
 
@@ -681,6 +730,9 @@
 /* Shared data */
 #undef SHARE_DIR
 
+/* The size of `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
 /* The size of `time_t', as computed by sizeof. */
 #undef SIZEOF_TIME_T
 
@@ -699,6 +751,9 @@
 /* Use win32 resources and API */
 #undef UB_ON_WINDOWS
 
+/* the SYSLOG_FACILITY to use, default LOG_DAEMON */
+#undef UB_SYSLOG_FACILITY
+
 /* default username */
 #undef UB_USERNAME
 
@@ -747,6 +802,9 @@
 /* Define to 1 to use ipsecmod support. */
 #undef USE_IPSECMOD
 
+/* Define to 1 to use ipset support */
+#undef USE_IPSET
+
 /* Define if you want to use internal select based events */
 #undef USE_MINI_EVENT
 
@@ -944,8 +1002,14 @@
 
 
 
+#ifndef _OPENBSD_SOURCE
+#define _OPENBSD_SOURCE 1
+#endif
+
 #ifndef UNBOUND_DEBUG
+# ifndef NDEBUG
 #  define NDEBUG
+# endif
 #endif
 
 /** Use small-ldns codebase */
@@ -1178,6 +1242,15 @@
 char *strptime(const char *s, const char *format, struct tm *tm);
 #endif
 
+#if !HAVE_DECL_REALLOCARRAY
+void *reallocarray(void *ptr, size_t nmemb, size_t size);
+#endif
+
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#include <bsd/stdlib.h>
+#endif
+
 #ifdef HAVE_LIBRESSL
 #  if !HAVE_DECL_STRLCPY
 size_t strlcpy(char *dst, const char *src, size_t siz);
@@ -1191,9 +1264,6 @@
 #  if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
 uint32_t arc4random_uniform(uint32_t upper_bound);
 #  endif
-#  if !HAVE_DECL_REALLOCARRAY
-void *reallocarray(void *ptr, size_t nmemb, size_t size);
-#  endif
 #endif /* HAVE_LIBRESSL */
 #ifndef HAVE_ARC4RANDOM
 int getentropy(void* buf, size_t len);
--- contrib/unbound/config.sub.orig
+++ contrib/unbound/config.sub
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/usr/bin/sh
 # Configuration validation subroutine script.
 #   Copyright 1992-2016 Free Software Foundation, Inc.
 
--- contrib/unbound/configure.orig
+++ contrib/unbound/configure
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unbound 1.8.1.
+# Generated by GNU Autoconf 2.69 for unbound 1.10.1.
 #
-# Report bugs to <unbound-bugs@nlnetlabs.nl>.
+# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -275,10 +275,11 @@
     $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
     $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: unbound-bugs@nlnetlabs.nl about your system, including
-$0: any error possibly output before this message. Then
-$0: install a modern shell, or manually run the script
-$0: under such a shell if you do have one."
+$0: unbound-bugs@nlnetlabs.nl or
+$0: https://github.com/NLnetLabs/unbound/issues about your
+$0: system, including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
   fi
   exit 1
 fi
@@ -590,9 +591,9 @@
 # Identity of this package.
 PACKAGE_NAME='unbound'
 PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.8.1'
-PACKAGE_STRING='unbound 1.8.1'
-PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
+PACKAGE_VERSION='1.10.1'
+PACKAGE_STRING='unbound 1.10.1'
+PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
 PACKAGE_URL=''
 
 # Factoring default headers for most tests.
@@ -638,6 +639,8 @@
 ALLTARGET
 SOURCEFILE
 SOURCEDETERMINE
+IPSET_OBJ
+IPSET_SRC
 IPSECMOD_HEADER
 IPSECMOD_OBJ
 DNSCRYPT_OBJ
@@ -664,12 +667,6 @@
 WINAPPS
 WINDRES
 CHECKLOCK_OBJ
-USE_SYSTEMD_FALSE
-USE_SYSTEMD_TRUE
-SYSTEMD_DAEMON_LIBS
-SYSTEMD_DAEMON_CFLAGS
-SYSTEMD_LIBS
-SYSTEMD_CFLAGS
 staticexe
 PC_LIBEVENT_DEPENDENCY
 UNBOUND_EVENT_UNINSTALL
@@ -676,8 +673,10 @@
 UNBOUND_EVENT_INSTALL
 SUBNET_HEADER
 SUBNET_OBJ
+PC_LIBBSD_DEPENDENCY
 SSLLIB
 HAVE_SSL
+PC_CRYPTO_DEPENDENCY
 CONFIG_DATE
 NETBSD_LINTFLAGS
 PYUNBOUND_UNINSTALL
@@ -694,9 +693,6 @@
 SWIG_LIB
 SWIG
 PC_PY_DEPENDENCY
-PKG_CONFIG_LIBDIR
-PKG_CONFIG_PATH
-PKG_CONFIG
 PY_MAJOR_VERSION
 PYTHON_SITE_PKG
 PYTHON_LDFLAGS
@@ -708,8 +704,19 @@
 PTHREAD_LIBS
 PTHREAD_CC
 ax_pthread_config
+ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ
+SLDNS_ALLOCCHECK_EXTRA_OBJ
+USE_SYSTEMD_FALSE
+USE_SYSTEMD_TRUE
+SYSTEMD_DAEMON_LIBS
+SYSTEMD_DAEMON_CFLAGS
+SYSTEMD_LIBS
+SYSTEMD_CFLAGS
 RUNTIME_PATH
 LIBOBJS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
 LT_SYS_LIBRARY_PATH
 OTOOL64
 OTOOL
@@ -841,11 +848,13 @@
 enable_libtool_lock
 enable_rpath
 enable_largefile
+enable_systemd
 enable_alloc_checks
 enable_alloc_lite
 enable_alloc_nonregional
 with_pthreads
 with_solaris_threads
+with_syslog_facility
 with_pyunbound
 with_pythonmodule
 enable_swig_version_check
@@ -852,6 +861,7 @@
 with_nss
 with_nettle
 with_ssl
+with_libbsd
 enable_sha1
 enable_sha2
 enable_subnet
@@ -867,7 +877,7 @@
 with_libexpat
 with_libhiredis
 enable_static_exe
-enable_systemd
+enable_fully_static
 enable_lock_checks
 enable_allsymbols
 enable_dnstap
@@ -878,6 +888,8 @@
 with_libsodium
 enable_cachedb
 enable_ipsecmod
+enable_ipset
+with_libmnl
 with_libunbound_only
 '
       ac_precious_vars='build_alias
@@ -892,7 +904,6 @@
 YACC
 YFLAGS
 LT_SYS_LIBRARY_PATH
-PYTHON_VERSION
 PKG_CONFIG
 PKG_CONFIG_PATH
 PKG_CONFIG_LIBDIR
@@ -899,7 +910,8 @@
 SYSTEMD_CFLAGS
 SYSTEMD_LIBS
 SYSTEMD_DAEMON_CFLAGS
-SYSTEMD_DAEMON_LIBS'
+SYSTEMD_DAEMON_LIBS
+PYTHON_VERSION'
 
 
 # Initialize some variables set by options.
@@ -1440,7 +1452,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures unbound 1.8.1 to adapt to many kinds of systems.
+\`configure' configures unbound 1.10.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1505,7 +1517,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of unbound 1.8.1:";;
+     short | recursive ) echo "Configuration of unbound 1.10.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1527,6 +1539,7 @@
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --disable-rpath         disable hardcoded rpath (default=enabled)
   --disable-largefile     omit support for large files
+  --enable-systemd        compile with systemd support
   --enable-alloc-checks   enable to memory allocation statistics, for debug
                           purposes
   --enable-alloc-lite     enable for lightweight alloc assertions, for debug
@@ -1552,8 +1565,8 @@
   --enable-tfo-client     Enable TCP Fast Open for client mode
   --enable-tfo-server     Enable TCP Fast Open for server mode
   --enable-static-exe     enable to compile executables statically against
-                          (event) libs, for debug purposes
-  --enable-systemd        compile with systemd support
+                          (event) uninstalled libs, for debug purposes
+  --enable-fully-static   enable to compile fully static
   --enable-lock-checks    enable to check lock and unlock calls, for debug
                           purposes
   --enable-allsymbols     export all symbols from libunbound and link binaries
@@ -1565,6 +1578,7 @@
                           storage
   --enable-ipsecmod       Enable ipsecmod module that facilitates
                           opportunistic IPsec
+  --enable-ipset          enable ipset module
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1598,6 +1612,8 @@
   --with-pthreads         use pthreads library, or --without-pthreads to
                           disable threading support.
   --with-solaris-threads  use solaris native thread library.
+  --with-syslog-facility=LOCAL0 - LOCAL7
+                          set SYSLOG_FACILITY, default DAEMON
   --with-pyunbound        build PyUnbound, or --without-pyunbound to skip it.
                           (default=no)
   --with-pythonmodule     build Python module, or --without-pythonmodule to
@@ -1607,6 +1623,7 @@
   --with-ssl=pathname     enable SSL (will check /usr/local/ssl /usr/lib/ssl
                           /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
                           /usr)
+  --with-libbsd           Use portable libbsd functions
   --with-libevent=pathname
                           use libevent (will check /usr/local /opt/local
                           /usr/lib /usr/pkg /usr/sfw /usr or you can specify
@@ -1619,6 +1636,7 @@
   --with-protobuf-c=path  Path where protobuf-c is installed, for dnstap
   --with-libfstrm=path    Path where libfstrm is installed, for dnstap
   --with-libsodium=path   Path where libsodium is installed, for dnscrypt
+  --with-libmnl=path      specify explicit path for libmnl.
   --with-libunbound-only  do not build daemon and tool programs
 
 Some influential environment variables:
@@ -1638,10 +1656,6 @@
               default value of `-d' given by some make applications.
   LT_SYS_LIBRARY_PATH
               User-defined run-time library search path.
-  PYTHON_VERSION
-              The installed Python version to use, for example '2.3'. This
-              string will be appended to the Python interpreter canonical
-              name.
   PKG_CONFIG  path to pkg-config utility
   PKG_CONFIG_PATH
               directories to add to pkg-config's search path
@@ -1655,11 +1669,15 @@
               C compiler flags for SYSTEMD_DAEMON, overriding pkg-config
   SYSTEMD_DAEMON_LIBS
               linker flags for SYSTEMD_DAEMON, overriding pkg-config
+  PYTHON_VERSION
+              The installed Python version to use, for example '2.3'. This
+              string will be appended to the Python interpreter canonical
+              name.
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <unbound-bugs@nlnetlabs.nl>.
+Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
 _ACEOF
 ac_status=$?
 fi
@@ -1722,7 +1740,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-unbound configure 1.8.1
+unbound configure 1.10.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1881,9 +1899,9 @@
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ---------------------------------------- ##
-## Report this to unbound-bugs@nlnetlabs.nl ##
-## ---------------------------------------- ##"
+( $as_echo "## --------------------------------------------------------------------------------------- ##
+## Report this to unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues ##
+## --------------------------------------------------------------------------------------- ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
@@ -2431,7 +2449,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by unbound $as_me 1.8.1, which was
+It was created by unbound $as_me 1.10.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2781,14 +2799,14 @@
 
 UNBOUND_VERSION_MAJOR=1
 
-UNBOUND_VERSION_MINOR=8
+UNBOUND_VERSION_MINOR=10
 
 UNBOUND_VERSION_MICRO=1
 
 
-LIBUNBOUND_CURRENT=8
-LIBUNBOUND_REVISION=1
-LIBUNBOUND_AGE=0
+LIBUNBOUND_CURRENT=9
+LIBUNBOUND_REVISION=8
+LIBUNBOUND_AGE=1
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
 # 1.0.2 had 0:14:0
@@ -2852,6 +2870,17 @@
 # 1.7.3 had 7:11:5
 # 1.8.0 had 8:0:0 # changes the event callback function signature
 # 1.8.1 had 8:1:0
+# 1.8.2 had 8:2:0
+# 1.8.3 had 8:3:0
+# 1.9.0 had 9:0:1 # add ub_ctx_set_tls
+# 1.9.1 had 9:1:1
+# 1.9.2 had 9:2:1
+# 1.9.3 had 9:3:1
+# 1.9.4 had 9:4:1
+# 1.9.5 had 9:5:1
+# 1.9.6 had 9:6:1
+# 1.10.0 had 9:7:1
+# 1.10.1 had 9:8:1
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -2875,6 +2904,14 @@
 
 
 
+
+cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
+
+cat >>confdefs.h <<_ACEOF
+#define CONFCMDLINE "$cmdln"
+_ACEOF
+
+
 CFLAGS="$CFLAGS"
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -14555,6 +14592,127 @@
 
 
 
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+fi
+
 # Checks for header files.
 for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h
 do :
@@ -14919,7 +15077,40 @@
 _ACEOF
 
 
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
+$as_echo_n "checking size of size_t... " >&6; }
+if ${ac_cv_sizeof_size_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t"        "$ac_includes_default"; then :
 
+else
+  if test "$ac_cv_type_size_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_size_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
+$as_echo "$ac_cv_sizeof_size_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+
 # add option to disable the evil rpath
 
 # Check whether --enable-rpath was given.
@@ -15967,7 +16158,7 @@
 
 
 # check if we can use SO_REUSEPORT
-if echo "$host" | grep -i -e linux -e dragonfly >/dev/null; then
+if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then
 
 $as_echo "#define REUSEPORT_DEFAULT 1" >>confdefs.h
 
@@ -15977,6 +16168,197 @@
 
 fi
 
+# Include systemd.m4 - begin
+#   macros for configuring systemd
+#   Copyright 2015, Sami Kerola, CloudFlare.
+#   BSD licensed.
+# Check whether --enable-systemd was given.
+if test "${enable_systemd+set}" = set; then :
+  enableval=$enable_systemd;
+else
+  enable_systemd=no
+fi
+
+have_systemd=no
+if test "x$enable_systemd" != xno; then :
+
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
+$as_echo_n "checking for SYSTEMD... " >&6; }
+
+if test -n "$SYSTEMD_CFLAGS"; then
+    pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$SYSTEMD_LIBS"; then
+    pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1`
+        else
+	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$SYSTEMD_PKG_ERRORS" >&5
+
+	have_systemd=no
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	have_systemd=no
+else
+	SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
+	SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	have_systemd=yes
+fi
+		if test "x$have_systemd" != "xyes"; then :
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5
+$as_echo_n "checking for SYSTEMD_DAEMON... " >&6; }
+
+if test -n "$SYSTEMD_DAEMON_CFLAGS"; then
+    pkg_cv_SYSTEMD_DAEMON_CFLAGS="$SYSTEMD_DAEMON_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_DAEMON_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$SYSTEMD_DAEMON_LIBS"; then
+    pkg_cv_SYSTEMD_DAEMON_LIBS="$SYSTEMD_DAEMON_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_DAEMON_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
+        else
+	        SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5
+
+	have_systemd_daemon=no
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	have_systemd_daemon=no
+else
+	SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS
+	SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	have_systemd_daemon=yes
+fi
+		if test "x$have_systemd_daemon" = "xyes"; then :
+  have_systemd=yes
+fi
+
+fi
+	case $enable_systemd:$have_systemd in #(
+  yes:no) :
+    as_fn_error $? "systemd enabled but libsystemd not found" "$LINENO" 5 ;; #(
+  *:yes) :
+
+$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h
+
+		LIBS="$LIBS $SYSTEMD_LIBS"
+
+	 ;; #(
+  *) :
+     ;;
+esac
+
+
+fi
+ if test "x$have_systemd" = xyes; then
+  USE_SYSTEMD_TRUE=
+  USE_SYSTEMD_FALSE='#'
+else
+  USE_SYSTEMD_TRUE='#'
+  USE_SYSTEMD_FALSE=
+fi
+
+
+# Include systemd.m4 - end
+
 # set memory allocation checking if requested
 # Check whether --enable-alloc-checks was given.
 if test "${enable_alloc_checks+set}" = set; then :
@@ -16002,6 +16384,10 @@
 
 $as_echo "#define UNBOUND_ALLOC_STATS 1" >>confdefs.h
 
+	SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
+
+	ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
+
 else
 	if test x_$enable_alloc_lite = x_yes; then
 
@@ -16765,6 +17151,26 @@
 
 fi # end of non-mingw check of thread libraries
 
+# Check for SYSLOG_FACILITY
+
+# Check whether --with-syslog-facility was given.
+if test "${with_syslog_facility+set}" = set; then :
+  withval=$with_syslog_facility;  UNBOUND_SYSLOG_FACILITY="$withval"
+fi
+
+case "${UNBOUND_SYSLOG_FACILITY}" in
+
+  LOCAL[0-7]) UNBOUND_SYSLOG_FACILITY="LOG_${UNBOUND_SYSLOG_FACILITY}" ;;
+
+           *) UNBOUND_SYSLOG_FACILITY="LOG_DAEMON" ;;
+
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define UB_SYSLOG_FACILITY ${UNBOUND_SYSLOG_FACILITY}
+_ACEOF
+
+
 # Check for PyUnbound
 
 # Check whether --with-pyunbound was given.
@@ -17012,126 +17418,6 @@
         CPPFLAGS="$PYTHON_CPPFLAGS"
       fi
       ub_have_python=yes
-
-
-
-
-
-
-
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
-	if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PKG_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $PKG_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
-fi
-PKG_CONFIG=$ac_cv_path_PKG_CONFIG
-if test -n "$PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
-$as_echo "$PKG_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_PKG_CONFIG"; then
-  ac_pt_PKG_CONFIG=$PKG_CONFIG
-  # Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $ac_pt_PKG_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
-fi
-ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
-if test -n "$ac_pt_PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
-$as_echo "$ac_pt_PKG_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_pt_PKG_CONFIG" = x; then
-    PKG_CONFIG=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    PKG_CONFIG=$ac_pt_PKG_CONFIG
-  fi
-else
-  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
-fi
-
-fi
-if test -n "$PKG_CONFIG"; then
-	_pkg_min_version=0.9.0
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
-$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
-	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-	else
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-		PKG_CONFIG=""
-	fi
-fi
       if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5
   ($PKG_CONFIG --exists --print-errors ""python${PY_MAJOR_VERSION}"") 2>&5
@@ -17478,8 +17764,10 @@
 	fi
         LIBS="$LIBS -lnss3 -lnspr4"
 	SSLLIB=""
+	PC_CRYPTO_DEPENDENCY="nss nspr"
 
 
+
 fi
 
 
@@ -17521,8 +17809,10 @@
 	fi
         LIBS="$LIBS -lhogweed -lnettle -lgmp"
 	SSLLIB=""
+	PC_CRYPTO_DEPENDENCY="hogweed nettle"
 
 
+
 fi
 
 
@@ -17871,6 +18161,9 @@
     conftest$ac_exeext conftest.$ac_ext
 SSLLIB="-lssl"
 
+PC_CRYPTO_DEPENDENCY="libcrypto libssl"
+
+
 # check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
 BAKLIBS="$LIBS"
 LIBS="-lssl $LIBS"
@@ -17961,17 +18254,7 @@
 cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_ARC4RANDOM_UNIFORM $ac_have_decl
 _ACEOF
-ac_fn_c_check_decl "$LINENO" "reallocarray" "ac_cv_have_decl_reallocarray" "$ac_includes_default"
-if test "x$ac_cv_have_decl_reallocarray" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_REALLOCARRAY $ac_have_decl
-_ACEOF
-
 else
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
@@ -17990,7 +18273,7 @@
 
 done
 
-for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify
+for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18006,7 +18289,7 @@
 # these check_funcs need -lssl
 BAKLIBS="$LIBS"
 LIBS="-lssl $LIBS"
-for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername
+for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18111,10 +18394,157 @@
 #define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO $ac_have_decl
 _ACEOF
 
+
+if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then
+# check function return type.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the return type of HMAC_Init_ex" >&5
+$as_echo_n "checking the return type of HMAC_Init_ex... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef HAVE_OPENSSL_ERR_H
+#include <openssl/err.h>
+#endif
+
+#ifdef HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+#ifdef HAVE_OPENSSL_CONF_H
+#include <openssl/conf.h>
+#endif
+
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+
+int
+main ()
+{
+
+	HMAC_CTX* hmac_ctx = NULL;
+	void* hmac_key = NULL;
+	const EVP_MD* digest = NULL;
+	int x = HMAC_Init_ex(hmac_ctx, hmac_key, 32, digest, NULL);
+	(void)x;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5
+$as_echo "int" >&6; }
+
+else
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5
+$as_echo "void" >&6; }
+
+$as_echo "#define HMAC_INIT_EX_RETURNS_VOID 1" >>confdefs.h
+
+
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
 
+fi
 
 
+# libbsd
+
+# Check whether --with-libbsd was given.
+if test "${with_libbsd+set}" = set; then :
+  withval=$with_libbsd;
+	for ac_header in bsd/string.h bsd/stdlib.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+	if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then
+		for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do
+			as_ac_Search=`$as_echo "ac_cv_search_$func" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing $func" >&5
+$as_echo_n "checking for library containing $func... " >&6; }
+if eval \${$as_ac_Search+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $func ();
+int
+main ()
+{
+return $func ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' bsd; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Search=\$ac_res"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if eval \${$as_ac_Search+:} false; then :
+  break
+fi
+done
+if eval \${$as_ac_Search+:} false; then :
+
+else
+  eval "$as_ac_Search=no"
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+eval ac_res=\$$as_ac_Search
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval ac_res=\$$as_ac_Search
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+
+$as_echo "#define HAVE_LIBBSD 1" >>confdefs.h
+
+				PC_LIBBSD_DEPENDENCY=libbsd
+
+
+fi
+
+		done
+	fi
+
+fi
+
+
 # Check whether --enable-sha1 was given.
 if test "${enable_sha1+set}" = set; then :
   enableval=$enable_sha1;
@@ -18417,9 +18847,7 @@
 
 use_dsa="no"
 case "$enable_dsa" in
-    no)
-      ;;
-    *)
+    yes)
       # detect if DSA is supported, and turn it off if not.
       if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
       ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new"
@@ -18472,6 +18900,10 @@
 
       fi
       ;;
+    *)
+      # disable dsa by default, RFC 8624 section 3.1, validators MUST NOT
+      # support DSA for DNSSEC Validation.
+      ;;
 esac
 
 # Check whether --enable-ed25519 was given.
@@ -19007,6 +19439,35 @@
 fi
 done
  # only in libev. (tested on 4.00)
+	for ac_func in event_assign
+do :
+  ac_fn_c_check_func "$LINENO" "event_assign" "ac_cv_func_event_assign"
+if test "x$ac_cv_func_event_assign" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_EVENT_ASSIGN 1
+_ACEOF
+
+fi
+done
+ # in libevent, for thread-safety
+	ac_fn_c_check_decl "$LINENO" "evsignal_assign" "ac_cv_have_decl_evsignal_assign" "$ac_includes_default
+#ifdef HAVE_EVENT_H
+#  include <event.h>
+#else
+#  include \"event2/event.h\"
+#endif
+
+"
+if test "x$ac_cv_have_decl_evsignal_assign" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_EVSIGNAL_ASSIGN $ac_have_decl
+_ACEOF
+
         PC_LIBEVENT_DEPENDENCY="libevent"
 
 	if test -n "$BAK_LDFLAGS_SET"; then
@@ -19137,7 +19598,7 @@
 
 fi
 
-# set static linking if requested
+# set static linking for uninstalled libraries if requested
 
 staticexe=""
 # Check whether --enable-static-exe was given.
@@ -19159,197 +19620,25 @@
 	fi
 fi
 
-# Include systemd.m4 - begin
-#   macros for configuring systemd
-#   Copyright 2015, Sami Kerola, CloudFlare.
-#   BSD licensed.
-# Check whether --enable-systemd was given.
-if test "${enable_systemd+set}" = set; then :
-  enableval=$enable_systemd;
-else
-  enable_systemd=no
+# set full static linking if requested
+# Check whether --enable-fully-static was given.
+if test "${enable_fully_static+set}" = set; then :
+  enableval=$enable_fully_static;
 fi
 
-have_systemd=no
-if test "x$enable_systemd" != xno; then :
-
-
-
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
-$as_echo_n "checking for SYSTEMD... " >&6; }
-
-if test -n "$SYSTEMD_CFLAGS"; then
-    pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
-else
-  pkg_failed=yes
+if test x_$enable_fully_static = x_yes; then
+	staticexe="-all-static"
+	if test "$on_mingw" = yes; then
+		# for static compile, include gdi32 and zlib here.
+		if echo $LIBS | grep 'lgdi32' >/dev/null; then
+			:
+		else
+			LIBS="$LIBS -lgdi32"
+		fi
+		LIBS="$LIBS -lz"
+	fi
 fi
- else
-    pkg_failed=untried
-fi
-if test -n "$SYSTEMD_LIBS"; then
-    pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
-else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
-fi
 
-
-
-if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
-        _pkg_short_errors_supported=yes
-else
-        _pkg_short_errors_supported=no
-fi
-        if test $_pkg_short_errors_supported = yes; then
-	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1`
-        else
-	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1`
-        fi
-	# Put the nasty error message in config.log where it belongs
-	echo "$SYSTEMD_PKG_ERRORS" >&5
-
-	have_systemd=no
-elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-	have_systemd=no
-else
-	SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
-	SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-	have_systemd=yes
-fi
-		if test "x$have_systemd" != "xyes"; then :
-
-
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5
-$as_echo_n "checking for SYSTEMD_DAEMON... " >&6; }
-
-if test -n "$SYSTEMD_DAEMON_CFLAGS"; then
-    pkg_cv_SYSTEMD_DAEMON_CFLAGS="$SYSTEMD_DAEMON_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_SYSTEMD_DAEMON_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
-else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
-fi
-if test -n "$SYSTEMD_DAEMON_LIBS"; then
-    pkg_cv_SYSTEMD_DAEMON_LIBS="$SYSTEMD_DAEMON_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_SYSTEMD_DAEMON_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
-else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
-fi
-
-
-
-if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
-        _pkg_short_errors_supported=yes
-else
-        _pkg_short_errors_supported=no
-fi
-        if test $_pkg_short_errors_supported = yes; then
-	        SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
-        else
-	        SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
-        fi
-	# Put the nasty error message in config.log where it belongs
-	echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5
-
-	have_systemd_daemon=no
-elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-	have_systemd_daemon=no
-else
-	SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS
-	SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-	have_systemd_daemon=yes
-fi
-		if test "x$have_systemd_daemon" = "xyes"; then :
-  have_systemd=yes
-fi
-
-fi
-	case $enable_systemd:$have_systemd in #(
-  yes:no) :
-    as_fn_error $? "systemd enabled but libsystemd not found" "$LINENO" 5 ;; #(
-  *:yes) :
-
-$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h
-
-		LIBS="$LIBS $SYSTEMD_LIBS"
-
-	 ;; #(
-  *) :
-     ;;
-esac
-
-
-fi
- if test "x$have_systemd" = xyes; then
-  USE_SYSTEMD_TRUE=
-  USE_SYSTEMD_FALSE='#'
-else
-  USE_SYSTEMD_TRUE='#'
-  USE_SYSTEMD_FALSE=
-fi
-
-
-# Include systemd.m4 - end
-
 # set lock checking if requested
 # Check whether --enable-lock_checks was given.
 if test "${enable_lock_checks+set}" = set; then :
@@ -19739,6 +20028,75 @@
 
 fi
 
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for htobe64" >&5
+$as_echo_n "checking for htobe64... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#ifdef HAVE_ENDIAN_H
+#  include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#  include <sys/endian.h>
+#endif
+
+int
+main ()
+{
+unsigned long long x = htobe64(0); printf("%u", (unsigned)x);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_HTOBE64 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for be64toh" >&5
+$as_echo_n "checking for be64toh... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#ifdef HAVE_ENDIAN_H
+#  include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#  include <sys/endian.h>
+#endif
+
+int
+main ()
+{
+unsigned long long x = be64toh(0); printf("%u", (unsigned)x);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_BE64TOH 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setusercontext" >&5
 $as_echo_n "checking for library containing setusercontext... " >&6; }
 if ${ac_cv_search_setusercontext+:} false; then :
@@ -20109,19 +20467,54 @@
 
 LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
 
-ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray"
-if test "x$ac_cv_func_reallocarray" = xyes; then :
-  $as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for reallocarray" >&5
+$as_echo_n "checking for reallocarray... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
 
+#ifndef _OPENBSD_SOURCE
+#define _OPENBSD_SOURCE 1
+#endif
+#include <stdlib.h>
+int main(void) {
+	void* p = reallocarray(NULL, 10, 100);
+	free(p);
+	return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h
+
+
 else
-  case " $LIBOBJS " in
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	case " $LIBOBJS " in
   *" reallocarray.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS reallocarray.$ac_objext"
  ;;
 esac
 
+
 fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+ac_fn_c_check_decl "$LINENO" "reallocarray" "ac_cv_have_decl_reallocarray" "$ac_includes_default"
+if test "x$ac_cv_have_decl_reallocarray" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
 
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_REALLOCARRAY $ac_have_decl
+_ACEOF
 
 if test "$USE_NSS" = "no"; then
 	ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random"
@@ -20290,6 +20683,14 @@
 fi
 
 			;;
+			*freebsd*|*FreeBSD)
+				case " $LIBOBJS " in
+  *" getentropy_freebsd.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getentropy_freebsd.$ac_objext"
+ ;;
+esac
+
+			;;
 			*linux*|Linux|*)
 				case " $LIBOBJS " in
   *" getentropy_linux.$ac_objext "* ) ;;
@@ -20990,6 +21391,59 @@
 		;;
 esac
 
+# check for ipset if requested
+# Check whether --enable-ipset was given.
+if test "${enable_ipset+set}" = set; then :
+  enableval=$enable_ipset;
+fi
+
+case "$enable_ipset" in
+    yes)
+
+$as_echo "#define USE_IPSET 1" >>confdefs.h
+
+		IPSET_SRC="ipset/ipset.c"
+
+		IPSET_OBJ="ipset.lo"
+
+
+		# mnl
+
+# Check whether --with-libmnl was given.
+if test "${with_libmnl+set}" = set; then :
+  withval=$with_libmnl;
+else
+   withval="yes"
+fi
+
+		found_libmnl="no"
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
+$as_echo_n "checking for libmnl... " >&6; }
+		if test x_$withval = x_ -o x_$withval = x_yes; then
+			withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
+		fi
+		for dir in $withval ; do
+			if test -f "$dir/include/libmnl/libmnl.h"; then
+				found_libmnl="yes"
+								if test "$dir" != "/usr"; then
+					CPPFLAGS="$CPPFLAGS -I$dir/include"
+					LDFLAGS="$LDFLAGS -L$dir/lib"
+				fi
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
+$as_echo "found in $dir" >&6; }
+				LIBS="$LIBS -lmnl"
+				break;
+			fi
+		done
+		if test x_$found_libmnl != x_yes; then
+			as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
+		fi
+		;;
+    no|*)
+    	# nothing
+		;;
+esac
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5
 $as_echo_n "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; }
 # on openBSD, the implicit rule make $< work.
@@ -21145,12 +21599,12 @@
 
 
 
-version=1.8.1
+version=1.10.1
 
 date=`date +'%b %e, %Y'`
 
 
-ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service"
+ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service"
 
 ac_config_headers="$ac_config_headers config.h"
 
@@ -21664,7 +22118,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by unbound $as_me 1.8.1, which was
+This file was extended by unbound $as_me 1.10.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21724,13 +22178,13 @@
 Configuration commands:
 $config_commands
 
-Report bugs to <unbound-bugs@nlnetlabs.nl>."
+Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>."
 
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-unbound config.status 1.8.1
+unbound config.status 1.10.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -22156,6 +22610,7 @@
     "contrib/libunbound.pc") CONFIG_FILES="$CONFIG_FILES contrib/libunbound.pc" ;;
     "contrib/unbound.socket") CONFIG_FILES="$CONFIG_FILES contrib/unbound.socket" ;;
     "contrib/unbound.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound.service" ;;
+    "contrib/unbound_portable.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound_portable.service" ;;
     "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
--- contrib/unbound/configure.ac.orig
+++ contrib/unbound/configure.ac
@@ -10,16 +10,16 @@
 
 # must be numbers. ac_defun because of later processing
 m4_define([VERSION_MAJOR],[1])
-m4_define([VERSION_MINOR],[8])
+m4_define([VERSION_MINOR],[10])
 m4_define([VERSION_MICRO],[1])
-AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
+AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
 AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
 AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
 AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
 
-LIBUNBOUND_CURRENT=8
-LIBUNBOUND_REVISION=1
-LIBUNBOUND_AGE=0
+LIBUNBOUND_CURRENT=9
+LIBUNBOUND_REVISION=8
+LIBUNBOUND_AGE=1
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
 # 1.0.2 had 0:14:0
@@ -83,6 +83,17 @@
 # 1.7.3 had 7:11:5
 # 1.8.0 had 8:0:0 # changes the event callback function signature
 # 1.8.1 had 8:1:0
+# 1.8.2 had 8:2:0
+# 1.8.3 had 8:3:0
+# 1.9.0 had 9:0:1 # add ub_ctx_set_tls
+# 1.9.1 had 9:1:1
+# 1.9.2 had 9:2:1
+# 1.9.3 had 9:3:1
+# 1.9.4 had 9:4:1
+# 1.9.5 had 9:5:1
+# 1.9.6 had 9:6:1
+# 1.10.0 had 9:7:1
+# 1.10.1 had 9:8:1
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -106,6 +117,10 @@
 AC_SUBST(LIBUNBOUND_REVISION)
 AC_SUBST(LIBUNBOUND_AGE)
 
+
+cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
+AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure])
+
 CFLAGS="$CFLAGS"
 AC_AIX
 if test "$ac_cv_header_minix_config_h" = "yes"; then
@@ -379,6 +394,8 @@
 AC_CHECK_TOOL(STRIP, strip)
 ACX_LIBTOOL_C_ONLY
 
+PKG_PROG_PKG_CONFIG
+
 # Checks for header files.
 AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
 
@@ -417,6 +434,7 @@
 # endif
 #endif
 ])
+AC_CHECK_SIZEOF(size_t)
 
 # add option to disable the evil rpath
 ACX_ARG_RPATH
@@ -462,12 +480,16 @@
 AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
 
 # check if we can use SO_REUSEPORT
-if echo "$host" | grep -i -e linux -e dragonfly >/dev/null; then
+if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then
 	AC_DEFINE(REUSEPORT_DEFAULT, 1, [if REUSEPORT is enabled by default])
 else
 	AC_DEFINE(REUSEPORT_DEFAULT, 0, [if REUSEPORT is enabled by default])
 fi
 
+# Include systemd.m4 - begin
+sinclude(systemd.m4)
+# Include systemd.m4 - end
+
 # set memory allocation checking if requested
 AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks],
 	[ enable to memory allocation statistics, for debug purposes ]), 
@@ -483,6 +505,10 @@
 fi
 if test x_$enable_alloc_checks = x_yes; then
 	AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
+	SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
+	AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ)
+	ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
+	AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ)
 else
 	if test x_$enable_alloc_lite = x_yes; then
 		AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
@@ -586,6 +612,18 @@
 
 fi # end of non-mingw check of thread libraries
 
+# Check for SYSLOG_FACILITY
+AC_ARG_WITH(syslog-facility, AC_HELP_STRING([--with-syslog-facility=LOCAL0 - LOCAL7], [ set SYSLOG_FACILITY, default DAEMON ]),
+	[ UNBOUND_SYSLOG_FACILITY="$withval" ], [])
+case "${UNBOUND_SYSLOG_FACILITY}" in
+
+  LOCAL[[0-7]]) UNBOUND_SYSLOG_FACILITY="LOG_${UNBOUND_SYSLOG_FACILITY}" ;;
+
+           *) UNBOUND_SYSLOG_FACILITY="LOG_DAEMON" ;;
+
+esac
+AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON])
+
 # Check for PyUnbound
 AC_ARG_WITH(pyunbound,
    AC_HELP_STRING([--with-pyunbound],
@@ -638,7 +676,6 @@
         CPPFLAGS="$PYTHON_CPPFLAGS"
       fi
       ub_have_python=yes
-      PKG_PROG_PKG_CONFIG
       PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],
                        [PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],
                        [PC_PY_DEPENDENCY="python"])
@@ -725,6 +762,8 @@
 	fi
         LIBS="$LIBS -lnss3 -lnspr4"
 	SSLLIB=""
+	PC_CRYPTO_DEPENDENCY="nss nspr"
+	AC_SUBST(PC_CRYPTO_DEPENDENCY)
 	]
 )
 
@@ -745,6 +784,8 @@
 	fi
         LIBS="$LIBS -lhogweed -lnettle -lgmp"
 	SSLLIB=""
+	PC_CRYPTO_DEPENDENCY="hogweed nettle"
+	AC_SUBST(PC_CRYPTO_DEPENDENCY)
 	]
 )
 
@@ -754,6 +795,9 @@
 ACX_LIB_SSL
 SSLLIB="-lssl"
 
+PC_CRYPTO_DEPENDENCY="libcrypto libssl"
+AC_SUBST(PC_CRYPTO_DEPENDENCY)
+
 # check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
 BAKLIBS="$LIBS"
 LIBS="-lssl $LIBS"
@@ -773,17 +817,17 @@
 	AC_DEFINE([HAVE_LIBRESSL], [1], [Define if we have LibreSSL])
 	# libressl provides these compat functions, but they may also be
 	# declared by the OS in libc.  See if they have been declared.
-	AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform,reallocarray])
+	AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform])
 else
 	AC_MSG_RESULT([no])
 fi
 AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
-AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify])
+AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
 
 # these check_funcs need -lssl
 BAKLIBS="$LIBS"
 LIBS="-lssl $LIBS"
-AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername])
+AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
 LIBS="$BAKLIBS"
 
 AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
@@ -806,9 +850,58 @@
 #include <openssl/ssl.h>
 #include <openssl/evp.h>
 ])
+
+if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then
+# check function return type.
+AC_MSG_CHECKING(the return type of HMAC_Init_ex)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+#ifdef HAVE_OPENSSL_ERR_H
+#include <openssl/err.h>
+#endif
+
+#ifdef HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+#ifdef HAVE_OPENSSL_CONF_H
+#include <openssl/conf.h>
+#endif
+
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+], [
+	HMAC_CTX* hmac_ctx = NULL;
+	void* hmac_key = NULL;
+	const EVP_MD* digest = NULL;
+	int x = HMAC_Init_ex(hmac_ctx, hmac_key, 32, digest, NULL);
+	(void)x;
+])], [
+	AC_MSG_RESULT(int)
+], [
+	AC_MSG_RESULT(void)
+	AC_DEFINE([HMAC_INIT_EX_RETURNS_VOID], 1, [If HMAC_Init_ex() returns void])
+])
 fi
+
+fi
 AC_SUBST(SSLLIB)
 
+# libbsd
+AC_ARG_WITH([libbsd], AC_HELP_STRING([--with-libbsd], [Use portable libbsd functions]), [
+	AC_CHECK_HEADERS([bsd/string.h bsd/stdlib.h],,, [AC_INCLUDES_DEFAULT])
+	if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then
+		for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do
+			AC_SEARCH_LIBS([$func], [bsd], [
+				AC_DEFINE(HAVE_LIBBSD, 1, [Use portable libbsd functions])
+				PC_LIBBSD_DEPENDENCY=libbsd
+				AC_SUBST(PC_LIBBSD_DEPENDENCY)
+			])
+		done
+	fi
+])
 
 AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support]))
 case "$enable_sha1" in
@@ -993,9 +1086,7 @@
 AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support]))
 use_dsa="no"
 case "$enable_dsa" in
-    no)
-      ;;
-    *)
+    yes)
       # detect if DSA is supported, and turn it off if not.
       if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
       AC_CHECK_FUNC(DSA_SIG_new, [
@@ -1026,6 +1117,10 @@
       AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
       fi
       ;;
+    *)
+      # disable dsa by default, RFC 8624 section 3.1, validators MUST NOT
+      # support DSA for DNSSEC Validation.
+      ;;
 esac
 
 AC_ARG_ENABLE(ed25519, AC_HELP_STRING([--disable-ed25519], [Disable ED25519 support]))
@@ -1194,6 +1289,14 @@
 	AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later
 	AC_CHECK_FUNCS([ev_loop]) # only in libev. (tested on 3.51)
 	AC_CHECK_FUNCS([ev_default_loop]) # only in libev. (tested on 4.00)
+	AC_CHECK_FUNCS([event_assign]) # in libevent, for thread-safety
+	AC_CHECK_DECLS([evsignal_assign], [], [], [AC_INCLUDES_DEFAULT
+#ifdef HAVE_EVENT_H
+#  include <event.h>
+#else
+#  include "event2/event.h"
+#endif
+	])
         PC_LIBEVENT_DEPENDENCY="libevent"
         AC_SUBST(PC_LIBEVENT_DEPENDENCY)
 	if test -n "$BAK_LDFLAGS_SET"; then
@@ -1262,11 +1365,11 @@
     ])
 fi
 
-# set static linking if requested
+# set static linking for uninstalled libraries if requested
 AC_SUBST(staticexe)
 staticexe=""
 AC_ARG_ENABLE(static-exe, AC_HELP_STRING([--enable-static-exe],
-	[ enable to compile executables statically against (event) libs, for debug purposes ]), 
+	[ enable to compile executables statically against (event) uninstalled libs, for debug purposes ]),
 	, )
 if test x_$enable_static_exe = x_yes; then
 	staticexe="-static"
@@ -1282,9 +1385,22 @@
 	fi
 fi
 
-# Include systemd.m4 - begin
-sinclude(systemd.m4)
-# Include systemd.m4 - end
+# set full static linking if requested
+AC_ARG_ENABLE(fully-static, AC_HELP_STRING([--enable-fully-static],
+	[ enable to compile fully static ]),
+	, )
+if test x_$enable_fully_static = x_yes; then
+	staticexe="-all-static"
+	if test "$on_mingw" = yes; then
+		# for static compile, include gdi32 and zlib here.
+		if echo $LIBS | grep 'lgdi32' >/dev/null; then
+			:
+		else
+			LIBS="$LIBS -lgdi32"
+		fi
+		LIBS="$LIBS -lz"
+	fi
+fi
 
 # set lock checking if requested
 AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
@@ -1375,6 +1491,35 @@
 #include <ws2tcpip.h>
 #endif
 ])
+
+AC_MSG_CHECKING([for htobe64])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <stdio.h>
+#ifdef HAVE_ENDIAN_H
+#  include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#  include <sys/endian.h>
+#endif
+], [unsigned long long x = htobe64(0); printf("%u", (unsigned)x);])],
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_HTOBE64, 1, [If we have htobe64]),
+  AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING([for be64toh])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <stdio.h>
+#ifdef HAVE_ENDIAN_H
+#  include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#  include <sys/endian.h>
+#endif
+], [unsigned long long x = be64toh(0); printf("%u", (unsigned)x);])],
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_BE64TOH, 1, [If we have be64toh]),
+  AC_MSG_RESULT(no))
+
 AC_SEARCH_LIBS([setusercontext], [util])
 AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4])
 AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
@@ -1433,7 +1578,25 @@
 dnl without CTIME, ARC4-functions and without reallocarray.
 LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
 AC_SUBST(LIBOBJ_WITHOUT_CTIMEARC4)
-AC_REPLACE_FUNCS(reallocarray)
+AC_MSG_CHECKING([for reallocarray])
+AC_LINK_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT
+[[
+#ifndef _OPENBSD_SOURCE
+#define _OPENBSD_SOURCE 1
+#endif
+#include <stdlib.h>
+int main(void) {
+	void* p = reallocarray(NULL, 10, 100);
+	free(p);
+	return 0;
+}
+]])], [AC_MSG_RESULT(yes)
+	AC_DEFINE(HAVE_REALLOCARRAY, 1, [If we have reallocarray(3)])
+], [
+	AC_MSG_RESULT(no)
+	AC_LIBOBJ(reallocarray)
+])
+AC_CHECK_DECLS([reallocarray])
 if test "$USE_NSS" = "no"; then
 	AC_REPLACE_FUNCS(arc4random)
 	AC_REPLACE_FUNCS(arc4random_uniform)
@@ -1460,6 +1623,9 @@
 				fi
 				AC_SEARCH_LIBS([clock_gettime], [rt])
 			;;
+			*freebsd*|*FreeBSD)
+				AC_LIBOBJ(getentropy_freebsd)
+			;;
 			*linux*|Linux|*)
 				AC_LIBOBJ(getentropy_linux)
 				AC_CHECK_FUNCS([SHA512_Update],,[
@@ -1572,6 +1738,47 @@
 		;;
 esac
 
+# check for ipset if requested
+AC_ARG_ENABLE(ipset, AC_HELP_STRING([--enable-ipset], [enable ipset module]))
+case "$enable_ipset" in
+    yes)
+		AC_DEFINE([USE_IPSET], [1], [Define to 1 to use ipset support])
+		IPSET_SRC="ipset/ipset.c"
+		AC_SUBST(IPSET_SRC)
+		IPSET_OBJ="ipset.lo"
+		AC_SUBST(IPSET_OBJ)
+
+		# mnl
+		AC_ARG_WITH(libmnl, AC_HELP_STRING([--with-libmnl=path],
+			[specify explicit path for libmnl.]),
+			[ ],[ withval="yes" ])
+		found_libmnl="no"
+		AC_MSG_CHECKING(for libmnl)
+		if test x_$withval = x_ -o x_$withval = x_yes; then
+			withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
+		fi
+		for dir in $withval ; do
+			if test -f "$dir/include/libmnl/libmnl.h"; then
+				found_libmnl="yes"
+				dnl assume /usr is in default path.
+				if test "$dir" != "/usr"; then
+					CPPFLAGS="$CPPFLAGS -I$dir/include"
+					LDFLAGS="$LDFLAGS -L$dir/lib"
+				fi
+				AC_MSG_RESULT(found in $dir)
+				LIBS="$LIBS -lmnl"
+				break;
+			fi
+		done
+		if test x_$found_libmnl != x_yes; then
+			AC_ERROR([Could not find libmnl, libmnl.h])
+		fi
+		;;
+    no|*)
+    	# nothing
+		;;
+esac
+
 AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
 # on openBSD, the implicit rule make $< work.
 # on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
@@ -1646,8 +1853,14 @@
 
 dnl includes
 [
+#ifndef _OPENBSD_SOURCE
+#define _OPENBSD_SOURCE 1
+#endif
+
 #ifndef UNBOUND_DEBUG
+# ifndef NDEBUG
 #  define NDEBUG
+# endif
 #endif
 
 /** Use small-ldns codebase */
@@ -1781,6 +1994,15 @@
 char *strptime(const char *s, const char *format, struct tm *tm);
 #endif
 
+#if !HAVE_DECL_REALLOCARRAY
+void *reallocarray(void *ptr, size_t nmemb, size_t size);
+#endif
+
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#include <bsd/stdlib.h>
+#endif
+
 #ifdef HAVE_LIBRESSL
 #  if !HAVE_DECL_STRLCPY
 size_t strlcpy(char *dst, const char *src, size_t siz);
@@ -1794,9 +2016,6 @@
 #  if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
 uint32_t arc4random_uniform(uint32_t upper_bound);
 #  endif
-#  if !HAVE_DECL_REALLOCARRAY
-void *reallocarray(void *ptr, size_t nmemb, size_t size);
-#  endif
 #endif /* HAVE_LIBRESSL */
 #ifndef HAVE_ARC4RANDOM
 int getentropy(void* buf, size_t len);
@@ -1885,6 +2104,6 @@
 AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
 AC_SUBST(date, [`date +'%b %e, %Y'`])
 
-AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service])
+AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
 AC_CONFIG_HEADER([config.h])
 AC_OUTPUT
--- contrib/unbound/contrib/README.orig
+++ contrib/unbound/contrib/README
@@ -27,10 +27,12 @@
   works like the BIND feature (removes AAAA records unless AAAA-only domain).
   Useful for certain 'broken IPv6 default route' scenarios.
   Patch from Stephane Lapie for ASAHI Net.
-* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
+* unbound_smf23.tar.gz: Solaris SMF installation/removal scripts.
   Contributed by Yuri Voinov.
 * unbound.socket and unbound.service: systemd files for unbound, install them
   in /usr/lib/systemd/system.  Contributed by Sami Kerola and Pavel Odintsov.
+* unbound_portable.service.in: systemd file for use unbound as portable service,
+  see comments in the file. Contributed by Frzk.
 * redirect-bogus.patch: Return configured address for bogus A and AAAA answers,
   instead of SERVFAIL. Contributed by SIDN.
 * fastrpz.patch: fastrpz support from Farsight Security.
@@ -38,3 +40,16 @@
 * unbound-querycachedb.py: utility to show data stored in cachedb backend
   for a particular query name and type.  It requires dnspython and (for
   redis backend) redis Python modules.
+* unbound-fuzzme.patch: adds unbound-fuzzme program that parses a packet from
+  stdin.  Used with fuzzers, patch from Jacob Hoffman-Andrews.
+* unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1
+  replacements for unbound-fuzzme.c that gets created after applying
+  the contrib/unbound-fuzzme.patch.  They are contributed by
+  Eric Sesterhenn from X41 D-Sec.
+* drop-tld.diff: adds option drop-tld: yesno that drops 2 label queries,
+  to stop random floods.  Apply with patch -p1 < contrib/drop-tld.diff and
+  compile.  From Saksham Manchanda (Secure64).  Please note that we think
+  this will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
+  lookups for downstream clients.
+* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
+  contributed by Andreas Schulze.
--- contrib/unbound/contrib/create_unbound_ad_servers.sh.orig
+++ contrib/unbound/contrib/create_unbound_ad_servers.sh
@@ -9,12 +9,13 @@
 # Variables
 dst_dir="/etc/opt/csw/unbound"
 work_dir="/tmp"
-list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
+list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
 
 # OS commands
 CAT=`which cat`
 ECHO=`which echo`
 WGET=`which wget`
+TR=`which tr`
 
 # Check Wget installed
 if [ ! -f $WGET ]; then
@@ -22,8 +23,10 @@
  exit 1
 fi
 
+# remove special characters with tr to protect unbound.conf
 $WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \
 $CAT $work_dir/yoyo_ad_servers | \
+$TR -d '";$\\' | \
 while read line ; \
  do \
    $ECHO "local-zone: \"$line\" redirect" ;\
@@ -36,4 +39,4 @@
 #  the unbound_ad_servers file:
 #
 #   include: $dst_dir/unbound_ad_servers
-#
\ No newline at end of file
+#
--- contrib/unbound/contrib/drop-tld.diff.orig
+++ contrib/unbound/contrib/drop-tld.diff
@@ -0,0 +1,82 @@
+diff --git a/daemon/worker.c b/daemon/worker.c
+index 263fcdd..f787b70 100644
+--- a/daemon/worker.c
++++ b/daemon/worker.c
+@@ -1213,6 +1213,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
+ 		addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
+ 		log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
+ 	}
++
++	if(worker->env.cfg->drop_tld) {
++		int lab = dname_count_labels(qinfo.qname);
++		if (lab == 2) {
++			comm_point_drop_reply(repinfo);
++			verbose(VERB_ALGO, "Dropping one label query.");
++			return 0;
++		}
++	}
+ 	if(qinfo.qtype == LDNS_RR_TYPE_AXFR || 
+ 		qinfo.qtype == LDNS_RR_TYPE_IXFR) {
+ 		verbose(VERB_ALGO, "worker request: refused zone transfer.");
+diff --git a/util/config_file.h b/util/config_file.h
+index b3ef930..2791541 100644
+--- a/util/config_file.h
++++ b/util/config_file.h
+@@ -274,6 +274,8 @@ struct config_file {
+ 	int prefetch_key;
+ 	/** deny queries of type ANY with an empty answer */
+ 	int deny_any;
++	/** Drop TLD queries from clients **/
++	int drop_tld;
+ 
+ 	/** chrootdir, if not "" or chroot will be done */
+ 	char* chrootdir;
+diff --git a/util/configlexer.lex b/util/configlexer.lex
+index a86ddf5..9bbedbb 100644
+--- a/util/configlexer.lex
++++ b/util/configlexer.lex
+@@ -299,6 +299,7 @@ private-domain{COLON}		{ YDVAR(1, VAR_PRIVATE_DOMAIN) }
+ prefetch-key{COLON}		{ YDVAR(1, VAR_PREFETCH_KEY) }
+ prefetch{COLON}			{ YDVAR(1, VAR_PREFETCH) }
+ deny-any{COLON}			{ YDVAR(1, VAR_DENY_ANY) }
++drop-tld{COLON}			{ YDVAR(1, VAR_DROP_TLD) }
+ stub-zone{COLON}		{ YDVAR(0, VAR_STUB_ZONE) }
+ name{COLON}			{ YDVAR(1, VAR_NAME) }
+ stub-addr{COLON}		{ YDVAR(1, VAR_STUB_ADDR) }
+diff --git a/util/configparser.y b/util/configparser.y
+index 10227a2..567d68e 100644
+--- a/util/configparser.y
++++ b/util/configparser.y
+@@ -164,6 +164,7 @@ extern struct config_parser_state* cfg_parser;
+ %token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
+ %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
+ %token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
++%token VAR_DROP_TLD
+ %token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
+ %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
+ %token VAR_TLS_SESSION_TICKET_KEYS
+@@ -266,6 +267,7 @@ content_server: server_num_threads | server_verbosity | server_port |
+ 	server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
+ 	server_fast_server_permil | server_fast_server_num  | server_tls_win_cert |
+ 	server_tcp_connection_limit | server_log_servfail | server_deny_any |
++	server_drop_tld |
+ 	server_unknown_server_time_limit | server_log_tag_queryreply |
+ 	server_stream_wait_size | server_tls_ciphers |
+ 	server_tls_ciphersuites | server_tls_session_ticket_keys
+@@ -1466,6 +1468,16 @@ server_deny_any: VAR_DENY_ANY STRING_ARG
+ 		free($2);
+ 	}
+ 	;
++
++server_drop_tld: VAR_DROP_TLD STRING_ARG
++	{
++		OUTYY(("P(server_drop_tld:%s)\n", $2));
++		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
++			yyerror("expected yes or no.");
++		else cfg_parser->cfg->drop_tld = (strcmp($2, "yes")==0);
++		free($2);
++	}
++	;
+ server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
+ 	{
+ 		OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
--- contrib/unbound/contrib/drop2rpz.orig
+++ contrib/unbound/contrib/drop2rpz
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+
+# usage: curl --silent https://www.spamhaus.org/drop/drop.txt | $0 > /path/to/spamhaus-drop.rpz.local
+#
+# unbound.conf:
+#  rpz:
+#    name: "spamhaus-drop.rpz.local."
+#    zonefile: "/path/tp/spamhaus-drop.rpz.local"
+#    rpz-log: yes
+#    rpz-log-name: "spamhaus-drop"
+#
+
+use strict;
+use vars qw{$o1 $o2 $o3 $o4 $m};
+
+# trailing dots required
+my $origin = 'drop.spamhaus.org.rpz.local.';
+my $mname  = 'localhost.';
+my $rname  = 'root.localhost.';
+my $ns     = $mname;
+
+my  $rpz_action = '.';         # return NXDOMAIN
+#my $rpz_action = '*.';        # return NODATA
+#my $rpz_action = 'rpz-drop.'; # drop the query
+
+print "$origin SOA $mname $rname 1 43200 7200 2419200 3600\n";
+print "$origin NS  $ns\n";
+while(<>) {
+  if(($o1, $o2, $o3, $o4, $m) = m{(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)}) {
+    print "$m.$o4.$o3.$o2.$o1.rpz-ip.$origin CNAME $rpz_action\n";
+  } else {
+    print "$_";
+  }
+}
+
+# add a testpoint: ask for "dns.google"
+# print "32.8.8.8.8.rpz-ip.$origin CNAME $rpz_action\n";
+
+exit;
--- contrib/unbound/contrib/fastrpz.patch.orig
+++ contrib/unbound/contrib/fastrpz.patch
@@ -1,11 +1,11 @@
 Description: based on the included patch contrib/fastrpz.patch
 Author: fastrpz@farsightsecurity.com
 ---
-Index: unboundfastrpz/Makefile.in
-===================================================================
---- unboundfastrpz/Makefile.in	(revision 4923)
-+++ unboundfastrpz/Makefile.in	(working copy)
-@@ -23,6 +23,8 @@
+diff --git a/Makefile.in b/Makefile.in
+index a20058cc..495779cc 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
  CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
  DNSTAP_SRC=@DNSTAP_SRC@
  DNSTAP_OBJ=@DNSTAP_OBJ@
@@ -14,25 +14,25 @@
  DNSCRYPT_SRC=@DNSCRYPT_SRC@
  DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
  WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
-@@ -126,7 +128,7 @@
+@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
  edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
  edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
  cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
--$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
-+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
+-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
++$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
  COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
  as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
  iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
-@@ -139,7 +141,7 @@
+@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \
  validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
  val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
  $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
--$(IPSECMOD_OBJ) respip.lo
-+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) respip.lo
+-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
++$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
  COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
  outside_network.lo
  COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
-@@ -405,6 +407,11 @@
+@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
  	$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
  	$(srcdir)/util/netevent.h
  
@@ -44,11 +44,11 @@
  # Python Module
  pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
  	pythonmod/interface.h \
-Index: unboundfastrpz/config.h.in
-===================================================================
---- unboundfastrpz/config.h.in	(revision 4923)
-+++ unboundfastrpz/config.h.in	(working copy)
-@@ -1272,4 +1272,11 @@
+diff --git a/config.h.in b/config.h.in
+index 78d47fed..e33073e4 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
  /** the version of unbound-control that this software implements */
  #define UNBOUND_CONTROL_VERSION 1
  
@@ -61,11 +61,11 @@
 +#undef FASTRPZ_LIB_OPEN
 +/** turn on fastrpz response policy zones */
 +#undef ENABLE_FASTRPZ
-Index: unboundfastrpz/configure.ac
-===================================================================
---- unboundfastrpz/configure.ac	(revision 4923)
-+++ unboundfastrpz/configure.ac	(working copy)
-@@ -6,6 +6,7 @@
+diff --git a/configure.ac b/configure.ac
+index 2b91dd3c..e6063d17 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
  sinclude(acx_python.m4)
  sinclude(ac_pkg_swig.m4)
  sinclude(dnstap/dnstap.m4)
@@ -73,7 +73,7 @@
  sinclude(dnscrypt/dnscrypt.m4)
  
  # must be numbers. ac_defun because of later processing
-@@ -1565,6 +1566,9 @@
+@@ -1778,6 +1779,9 @@ case "$enable_ipset" in
  		;;
  esac
  
@@ -83,10 +83,10 @@
  AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
  # on openBSD, the implicit rule make $< work.
  # on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
-Index: unboundfastrpz/daemon/daemon.c
-===================================================================
---- unboundfastrpz/daemon/daemon.c	(revision 4923)
-+++ unboundfastrpz/daemon/daemon.c	(working copy)
+diff --git a/daemon/daemon.c b/daemon/daemon.c
+index 8b0fc348..7ffb9221 100644
+--- a/daemon/daemon.c
++++ b/daemon/daemon.c
 @@ -91,6 +91,9 @@
  #include "sldns/keyraw.h"
  #include "respip/respip.h"
@@ -97,10 +97,12 @@
  
  #ifdef HAVE_SYSTEMD
  #include <systemd/sd-daemon.h>
-@@ -462,6 +465,14 @@
+@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon)
+ 		dt_apply_cfg(daemon->dtenv, daemon->cfg);
+ #else
  		fatal_exit("dnstap enabled in config but not built with dnstap support");
- #endif
- 	}
++#endif
++	}
 +	if(daemon->cfg->rpz_enable) {
 +#ifdef ENABLE_FASTRPZ
 +		rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg);
@@ -107,26 +109,24 @@
 +#else
 +		fatal_exit("fastrpz enabled in config"
 +			   " but not built with fastrpz");
-+#endif
-+	}
+ #endif
+ 	}
  	for(i=0; i<daemon->num; i++) {
- 		if(!(daemon->workers[i] = worker_create(daemon, i,
- 			shufport+numport*i/daemon->num, 
-@@ -719,6 +730,9 @@
+@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon)
+ #ifdef USE_DNSCRYPT
  	dnsc_delete(daemon->dnscenv);
  	daemon->dnscenv = NULL;
- #endif
++#endif
 +#ifdef ENABLE_FASTRPZ
 +	rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
-+#endif
+ #endif
  	daemon->cfg = NULL;
  }
- 
-Index: unboundfastrpz/daemon/daemon.h
-===================================================================
---- unboundfastrpz/daemon/daemon.h	(revision 4923)
-+++ unboundfastrpz/daemon/daemon.h	(working copy)
-@@ -136,6 +136,11 @@
+diff --git a/daemon/daemon.h b/daemon/daemon.h
+index 3effbafb..4d4c34da 100644
+--- a/daemon/daemon.h
++++ b/daemon/daemon.h
+@@ -138,6 +138,11 @@ struct daemon {
  	/** the dnscrypt environment */
  	struct dnsc_env* dnscenv;
  #endif
@@ -138,11 +138,11 @@
  };
  
  /**
-Index: unboundfastrpz/daemon/worker.c
-===================================================================
---- unboundfastrpz/daemon/worker.c	(revision 4923)
-+++ unboundfastrpz/daemon/worker.c	(working copy)
-@@ -75,6 +75,9 @@
+diff --git a/daemon/worker.c b/daemon/worker.c
+index eb7fdf2f..1982228d 100644
+--- a/daemon/worker.c
++++ b/daemon/worker.c
+@@ -76,6 +76,9 @@
  #include "libunbound/context.h"
  #include "libunbound/libworker.h"
  #include "sldns/sbuffer.h"
@@ -152,7 +152,7 @@
  #include "sldns/wire2str.h"
  #include "util/shm_side/shm_main.h"
  #include "dnscrypt/dnscrypt.h"
-@@ -533,8 +536,27 @@
+@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
  			/* not secure */
  			secure = 0;
  			break;
@@ -180,10 +180,10 @@
  	/* return this delegation from the cache */
  	edns_bak = *edns;
  	edns->edns_version = EDNS_ADVERTISED_VERSION;
-@@ -702,6 +724,23 @@
- 			secure = 0;
+@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
+ 			*is_secure_answer = 0;
  		}
- 	} else	secure = 0;
+ 	} else *is_secure_answer = 0;
 +#ifdef ENABLE_FASTRPZ
 +	if(repinfo->rpz) {
 +		/* Scan the cached answer for RPZ hits.
@@ -204,7 +204,7 @@
  
  	edns_bak = *edns;
  	edns->edns_version = EDNS_ADVERTISED_VERSION;
-@@ -1407,6 +1446,15 @@
+@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
  		log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
  			&repinfo->addr, repinfo->addrlen);
  		goto send_reply;
@@ -220,14 +220,14 @@
  	}
  
  	/* If we've found a local alias, replace the qname with the alias
-@@ -1455,12 +1503,21 @@
+@@ -1485,12 +1533,21 @@ lookup_cache:
  		h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
  		if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
  			/* answer from cache - we have acquired a readlock on it */
 -			if(answer_from_cache(worker, &qinfo,
 +			ret = answer_from_cache(worker, &qinfo,
- 				cinfo, &need_drop, &alias_rrset, &partial_rep,
- 				(struct reply_info*)e->data,
+ 				cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
+ 				&alias_rrset, &partial_rep, (struct reply_info*)e->data,
  				*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
  				sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
 -				&edns)) {
@@ -244,7 +244,7 @@
  				/* prefetch it if the prefetch TTL expired.
  				 * Note that if there is more than one pass
  				 * its qname must be that used for cache
-@@ -1514,11 +1571,19 @@
+@@ -1547,11 +1604,19 @@ lookup_cache:
  			lock_rw_unlock(&e->lock);
  		}
  		if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
@@ -266,11 +266,11 @@
  				goto send_reply;
  			}
  			verbose(VERB_ALGO, "answer norec from cache -- "
-Index: unboundfastrpz/doc/unbound.conf.5.in
-===================================================================
---- unboundfastrpz/doc/unbound.conf.5.in	(revision 4923)
-+++ unboundfastrpz/doc/unbound.conf.5.in	(working copy)
-@@ -1728,6 +1728,81 @@
+diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
+index 38c2d298..3b07f392 100644
+--- a/doc/unbound.conf.5.in
++++ b/doc/unbound.conf.5.in
+@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is
  used by dns64 processing instead.  Can be entered multiple times, list a
  new domain for which it applies, one per line.  Applies also to names
  underneath the name given.
@@ -352,10 +352,11 @@
  .SS "DNSCrypt Options"
  .LP
  The
-Index: unboundfastrpz/fastrpz/librpz.h
-===================================================================
---- unboundfastrpz/fastrpz/librpz.h	(nonexistent)
-+++ unboundfastrpz/fastrpz/librpz.h	(working copy)
+diff --git a/fastrpz/librpz.h b/fastrpz/librpz.h
+new file mode 100644
+index 00000000..645279d1
+--- /dev/null
++++ b/fastrpz/librpz.h
 @@ -0,0 +1,957 @@
 +/*
 + * Define the interface from a DNS resolver to the Response Policy Zone
@@ -1314,10 +1315,11 @@
 +#endif /* LIBRPZ_LIB_OPEN */
 +
 +#endif /* LIBRPZ_H */
-Index: unboundfastrpz/fastrpz/rpz.c
-===================================================================
---- unboundfastrpz/fastrpz/rpz.c	(nonexistent)
-+++ unboundfastrpz/fastrpz/rpz.c	(working copy)
+diff --git a/fastrpz/rpz.c b/fastrpz/rpz.c
+new file mode 100644
+index 00000000..c5ab7801
+--- /dev/null
++++ b/fastrpz/rpz.c
 @@ -0,0 +1,1352 @@
 +/*
 + * fastrpz/rpz.c - interface to the fastrpz response policy zone library
@@ -2671,10 +2673,11 @@
 +}
 +
 +#endif /* ENABLE_FASTRPZ */
-Index: unboundfastrpz/fastrpz/rpz.h
-===================================================================
---- unboundfastrpz/fastrpz/rpz.h	(nonexistent)
-+++ unboundfastrpz/fastrpz/rpz.h	(working copy)
+diff --git a/fastrpz/rpz.h b/fastrpz/rpz.h
+new file mode 100644
+index 00000000..5d7e31c5
+--- /dev/null
++++ b/fastrpz/rpz.h
 @@ -0,0 +1,138 @@
 +/*
 + * fastrpz/rpz.h - interface to the fastrpz response policy zone library
@@ -2814,10 +2817,11 @@
 +
 +#endif /* ENABLE_FASTRPZ */
 +#endif /* UNBOUND_FASTRPZ_RPZ_H */
-Index: unboundfastrpz/fastrpz/rpz.m4
-===================================================================
---- unboundfastrpz/fastrpz/rpz.m4	(nonexistent)
-+++ unboundfastrpz/fastrpz/rpz.m4	(working copy)
+diff --git a/fastrpz/rpz.m4 b/fastrpz/rpz.m4
+new file mode 100644
+index 00000000..21235355
+--- /dev/null
++++ b/fastrpz/rpz.m4
 @@ -0,0 +1,64 @@
 +# fastrpz/rpz.m4
 +
@@ -2883,10 +2887,10 @@
 +    AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
 +  fi
 +])
-Index: unboundfastrpz/iterator/iterator.c
-===================================================================
---- unboundfastrpz/iterator/iterator.c	(revision 4923)
-+++ unboundfastrpz/iterator/iterator.c	(working copy)
+diff --git a/iterator/iterator.c b/iterator/iterator.c
+index 1e0113a8..2fcbf547 100644
+--- a/iterator/iterator.c
++++ b/iterator/iterator.c
 @@ -68,6 +68,9 @@
  #include "sldns/str2wire.h"
  #include "sldns/parseutil.h"
@@ -2895,9 +2899,9 @@
 +#include "fastrpz/rpz.h"
 +#endif
  
- int 
- iter_init(struct module_env* env, int id)
-@@ -525,6 +528,23 @@
+ /* in msec */
+ int UNKNOWN_SERVER_NICENESS = 376;
+@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
  		if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
  			query_dname_compare(*mname, r->rk.dname) == 0 &&
  			!iter_find_rrset_in_prepend_answer(iq, r)) {
@@ -2921,7 +2925,7 @@
  			/* Add this relevant CNAME rrset to the prepend list.*/
  			if(!iter_add_prepend_answer(qstate, iq, r))
  				return 0;
-@@ -533,6 +553,9 @@
+@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
  
  		/* Other rrsets in the section are ignored. */
  	}
@@ -2931,7 +2935,7 @@
  	/* add authority rrsets to authority prepend, for wildcarded CNAMEs */
  	for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
  		msg->rep->ns_numrrsets; i++) {
-@@ -1216,6 +1239,7 @@
+@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
  	uint8_t* delname;
  	size_t delnamelen;
  	struct dns_msg* msg = NULL;
@@ -2939,7 +2943,7 @@
  
  	log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
  	/* check effort */
-@@ -1302,8 +1326,7 @@
+@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
  	}
  	if(msg) {
  		/* handle positive cache response */
@@ -2949,7 +2953,7 @@
  		if(verbosity >= VERB_ALGO) {
  			log_dns_msg("msg from cache lookup", &msg->qinfo, 
  				msg->rep);
-@@ -1311,7 +1334,22 @@
+@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
  				(int)msg->rep->ttl, 
  				(int)msg->rep->prefetch_ttl);
  		}
@@ -2972,7 +2976,7 @@
  		if(type == RESPONSE_TYPE_CNAME) {
  			uint8_t* sname = 0;
  			size_t slen = 0;
-@@ -2716,6 +2754,62 @@
+@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
  			sock_list_insert(&qstate->reply_origin, 
  				&qstate->reply->addr, qstate->reply->addrlen, 
  				qstate->region);
@@ -3035,7 +3039,7 @@
  		if(iq->minimisation_state != DONOT_MINIMISE_STATE
  			&& !(iq->chase_flags & BIT_RD)) {
  			if(FLAGS_GET_RCODE(iq->response->rep->flags) != 
-@@ -3462,6 +3556,10 @@
+@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
  		 * but only if we did recursion. The nonrecursion referral
  		 * from cache does not need to be stored in the msg cache. */
  		if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
@@ -3046,7 +3050,6 @@
  			iter_dns_store(qstate->env, &qstate->qinfo, 
  				iq->response->rep, 0, qstate->prefetch_leeway,
  				iq->dp&&iq->dp->has_parent_side_NS,
-@@ -3468,6 +3566,34 @@
  				qstate->region, qstate->query_flags);
  		}
  	}
@@ -3081,11 +3084,11 @@
  	qstate->return_rcode = LDNS_RCODE_NOERROR;
  	qstate->return_msg = iq->response;
  	return 0;
-Index: unboundfastrpz/iterator/iterator.h
-===================================================================
---- unboundfastrpz/iterator/iterator.h	(revision 4923)
-+++ unboundfastrpz/iterator/iterator.h	(working copy)
-@@ -386,6 +386,16 @@
+diff --git a/iterator/iterator.h b/iterator/iterator.h
+index a2f1b570..e1e4a738 100644
+--- a/iterator/iterator.h
++++ b/iterator/iterator.h
+@@ -386,6 +386,16 @@ struct iter_qstate {
  	 */
  	int minimise_count;
  
@@ -3102,11 +3105,11 @@
  	/**
  	 * Count number of time-outs. Used to prevent resolving failures when
  	 * the QNAME minimisation QTYPE is blocked. */
-Index: unboundfastrpz/services/cache/dns.c
-===================================================================
---- unboundfastrpz/services/cache/dns.c	(revision 4923)
-+++ unboundfastrpz/services/cache/dns.c	(working copy)
-@@ -928,6 +928,14 @@
+diff --git a/services/cache/dns.c b/services/cache/dns.c
+index 2a5bca4a..6de8863a 100644
+--- a/services/cache/dns.c
++++ b/services/cache/dns.c
+@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
  	struct regional* region, uint32_t flags)
  {
  	struct reply_info* rep = NULL;
@@ -3121,11 +3124,11 @@
  	/* alloc, malloc properly (not in region, like msg is) */
  	rep = reply_info_copy(msgrep, env->alloc, NULL);
  	if(!rep)
-Index: unboundfastrpz/services/mesh.c
-===================================================================
---- unboundfastrpz/services/mesh.c	(revision 4923)
-+++ unboundfastrpz/services/mesh.c	(working copy)
-@@ -60,6 +60,9 @@
+diff --git a/services/mesh.c b/services/mesh.c
+index 9114ef4c..3dc518e5 100644
+--- a/services/mesh.c
++++ b/services/mesh.c
+@@ -61,6 +61,9 @@
  #include "sldns/wire2str.h"
  #include "services/localzone.h"
  #include "util/data/dname.h"
@@ -3133,9 +3136,9 @@
 +#include "fastrpz/rpz.h"
 +#endif
  #include "respip/respip.h"
+ #include "services/listen_dnsport.h"
  
- /** subtract timers and the values do not overflow or become negative */
-@@ -1057,6 +1060,13 @@
+@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
  	else	secure = 0;
  	if(!rep && rcode == LDNS_RCODE_NOERROR)
  		rcode = LDNS_RCODE_SERVFAIL;
@@ -3149,7 +3152,7 @@
  	/* send the reply */
  	/* We don't reuse the encoded answer if either the previous or current
  	 * response has a local alias.  We could compare the alias records
-@@ -1230,6 +1240,7 @@
+@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
  	key.s.is_valrec = valrec;
  	key.s.qinfo = *qinfo;
  	key.s.query_flags = qflags;
@@ -3157,7 +3160,7 @@
  	/* We are searching for a similar mesh state when we DO want to
  	 * aggregate the state. Thus unique is set to NULL. (default when we
  	 * desire aggregation).*/
-@@ -1276,6 +1287,10 @@
+@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
  	if(!r)
  		return 0;
  	r->query_reply = *rep;
@@ -3168,11 +3171,11 @@
  	r->edns = *edns;
  	if(edns->opt_list) {
  		r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
-Index: unboundfastrpz/util/config_file.c
-===================================================================
---- unboundfastrpz/util/config_file.c	(revision 4923)
-+++ unboundfastrpz/util/config_file.c	(working copy)
-@@ -1386,6 +1386,8 @@
+diff --git a/util/config_file.c b/util/config_file.c
+index 52ca5a18..0660248f 100644
+--- a/util/config_file.c
++++ b/util/config_file.c
+@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg)
  	free(cfg->dnstap_socket_path);
  	free(cfg->dnstap_identity);
  	free(cfg->dnstap_version);
@@ -3180,12 +3183,12 @@
 +		free(cfg->rpz_cstr);
  	config_deldblstrlist(cfg->ratelimit_for_domain);
  	config_deldblstrlist(cfg->ratelimit_below_domain);
- #ifdef USE_IPSECMOD
-Index: unboundfastrpz/util/config_file.h
-===================================================================
---- unboundfastrpz/util/config_file.h	(revision 4923)
-+++ unboundfastrpz/util/config_file.h	(working copy)
-@@ -468,6 +468,11 @@
+ 	config_delstrlist(cfg->python_script);
+diff --git a/util/config_file.h b/util/config_file.h
+index 8739ca2a..a2dcf215 100644
+--- a/util/config_file.h
++++ b/util/config_file.h
+@@ -499,6 +499,11 @@ struct config_file {
  	/** true to disable DNSSEC lameness check in iterator */
  	int disable_dnssec_lame_check;
  
@@ -3197,11 +3200,11 @@
  	/** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
  	int ip_ratelimit;
  	/** number of slabs for ip_ratelimit cache */
-Index: unboundfastrpz/util/configlexer.lex
-===================================================================
---- unboundfastrpz/util/configlexer.lex	(revision 4923)
-+++ unboundfastrpz/util/configlexer.lex	(working copy)
-@@ -429,6 +429,10 @@
+diff --git a/util/configlexer.lex b/util/configlexer.lex
+index deedffa5..301458a3 100644
+--- a/util/configlexer.lex
++++ b/util/configlexer.lex
+@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON}	{
  		YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
  dnstap-log-forwarder-response-messages{COLON}	{
  		YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
@@ -3212,11 +3215,11 @@
  disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
  ip-ratelimit{COLON}		{ YDVAR(1, VAR_IP_RATELIMIT) }
  ratelimit{COLON}		{ YDVAR(1, VAR_RATELIMIT) }
-Index: unboundfastrpz/util/configparser.y
-===================================================================
---- unboundfastrpz/util/configparser.y	(revision 4923)
-+++ unboundfastrpz/util/configparser.y	(working copy)
-@@ -125,6 +125,7 @@
+diff --git a/util/configparser.y b/util/configparser.y
+index d471babe..cb6b1d63 100644
+--- a/util/configparser.y
++++ b/util/configparser.y
+@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
  %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
  %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
  %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
@@ -3224,7 +3227,7 @@
  %token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
  %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
  %token VAR_DISABLE_DNSSEC_LAME_CHECK
-@@ -164,7 +165,7 @@
+@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser;
  
  %%
  toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -3233,8 +3236,8 @@
  	forwardstart contents_forward | pythonstart contents_py | 
  	rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
  	dnscstart contents_dnsc | cachedbstart contents_cachedb |
-@@ -2546,6 +2547,50 @@
- 			(strcmp($2, "yes")==0);
+@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
+ 		free($2);
  	}
  	;
 +rpzstart: VAR_RPZ
@@ -3261,8 +3264,8 @@
 +
 +		OUTYY(("P(rpz_zone:%s)\n", $2));
 +		old_cstr = cfg_parser->cfg->rpz_cstr;
-+		(void)asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2);
-+		if(!new_cstr)
++		if(asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
++		else if(!new_cstr)
 +			yyerror("out of memory");
 +		free(old_cstr);
 +		cfg_parser->cfg->rpz_cstr = new_cstr;
@@ -3274,8 +3277,8 @@
 +
 +		OUTYY(("P(rpz_option:%s)\n", $2));
 +		old_cstr = cfg_parser->cfg->rpz_cstr;
-+		(void)asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2);
-+		if(!new_cstr)
++		if(asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
++		else if(!new_cstr)
 +			yyerror("out of memory");
 +		free(old_cstr);
 +		cfg_parser->cfg->rpz_cstr = new_cstr;
@@ -3284,11 +3287,11 @@
  pythonstart: VAR_PYTHON
  	{ 
  		OUTYY(("\nP(python:)\n")); 
-Index: unboundfastrpz/util/data/msgencode.c
-===================================================================
---- unboundfastrpz/util/data/msgencode.c	(revision 4923)
-+++ unboundfastrpz/util/data/msgencode.c	(working copy)
-@@ -585,6 +585,35 @@
+diff --git a/util/data/msgencode.c b/util/data/msgencode.c
+index be69f628..f10773aa 100644
+--- a/util/data/msgencode.c
++++ b/util/data/msgencode.c
+@@ -592,6 +592,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
  	return RETVAL_OK;
  }
  
@@ -3324,10 +3327,10 @@
  /** store query section in wireformat buffer, return RETVAL */
  static int
  insert_query(struct query_info* qinfo, struct compress_tree_node** tree, 
-@@ -748,6 +777,19 @@
- 			return 0;
+@@ -779,6 +808,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
+ 			}
+ 			sldns_buffer_write_u16_at(buffer, 10, arcount);
  		}
- 		sldns_buffer_write_u16_at(buffer, 10, arcount);
 +#ifdef ENABLE_FASTRPZ
 +	} else if(rep->security == sec_status_rpz_rewritten) {
 +		/* Insert the RPZ SOA for rpz even with MINIMAL_RESPONSES */
@@ -3344,11 +3347,11 @@
  	}
  	sldns_buffer_flip(buffer);
  	return 1;
-Index: unboundfastrpz/util/data/packed_rrset.c
-===================================================================
---- unboundfastrpz/util/data/packed_rrset.c	(revision 4923)
-+++ unboundfastrpz/util/data/packed_rrset.c	(working copy)
-@@ -255,6 +255,10 @@
+diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c
+index 4b0294f9..3b3838f6 100644
+--- a/util/data/packed_rrset.c
++++ b/util/data/packed_rrset.c
+@@ -256,6 +256,10 @@ sec_status_to_string(enum sec_status s)
  	case sec_status_insecure: 	return "sec_status_insecure";
  	case sec_status_secure_sentinel_fail: 	return "sec_status_secure_sentinel_fail";
  	case sec_status_secure: 	return "sec_status_secure";
@@ -3359,11 +3362,11 @@
  	}
  	return "unknown_sec_status_value";
  }
-Index: unboundfastrpz/util/data/packed_rrset.h
-===================================================================
---- unboundfastrpz/util/data/packed_rrset.h	(revision 4923)
-+++ unboundfastrpz/util/data/packed_rrset.h	(working copy)
-@@ -193,7 +193,15 @@
+diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h
+index 729877ba..ccd1a0c2 100644
+--- a/util/data/packed_rrset.h
++++ b/util/data/packed_rrset.h
+@@ -193,7 +193,15 @@ enum sec_status {
  	sec_status_secure_sentinel_fail,
  	/** SECURE means that the object (RRset or message) validated 
  	 * according to local policy. */
@@ -3380,11 +3383,11 @@
  };
  
  /**
-Index: unboundfastrpz/util/netevent.c
-===================================================================
---- unboundfastrpz/util/netevent.c	(revision 4923)
-+++ unboundfastrpz/util/netevent.c	(working copy)
-@@ -56,6 +56,9 @@
+diff --git a/util/netevent.c b/util/netevent.c
+index 9fe5da2d..037e70d1 100644
+--- a/util/netevent.c
++++ b/util/netevent.c
+@@ -57,6 +57,9 @@
  #ifdef HAVE_OPENSSL_ERR_H
  #include <openssl/err.h>
  #endif
@@ -3394,7 +3397,7 @@
  
  /* -------- Start of local definitions -------- */
  /** if CMSG_ALIGN is not defined on this platform, a workaround */
-@@ -588,6 +591,9 @@
+@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
  	struct cmsghdr* cmsg;
  #endif /* S_SPLINT_S */
  
@@ -3404,7 +3407,7 @@
  	rep.c = (struct comm_point*)arg;
  	log_assert(rep.c->type == comm_udp);
  
-@@ -677,6 +683,9 @@
+@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
  	int i;
  	struct sldns_buffer *buffer;
  
@@ -3414,7 +3417,7 @@
  	rep.c = (struct comm_point*)arg;
  	log_assert(rep.c->type == comm_udp);
  
-@@ -720,6 +729,9 @@
+@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
  			(void)comm_point_send_udp_msg(rep.c, buffer,
  				(struct sockaddr*)&rep.addr, rep.addrlen);
  		}
@@ -3424,9 +3427,9 @@
  		if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
  		another UDP port. Note rep.c cannot be reused with TCP fd. */
  			break;
-@@ -3035,6 +3047,9 @@
- 		comm_point_start_listening(repinfo->c, -1,
- 			repinfo->c->tcp_timeout_msec);
+@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
+ 				repinfo->c->tcp_timeout_msec);
+ 		}
  	}
 +#ifdef ENABLE_FASTRPZ
 +	rpz_end(repinfo);
@@ -3434,9 +3437,9 @@
  }
  
  void 
-@@ -3044,6 +3059,9 @@
+@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
  		return;
- 	log_assert(repinfo && repinfo->c);
+ 	log_assert(repinfo->c);
  	log_assert(repinfo->c->type != comm_tcp_accept);
 +#ifdef ENABLE_FASTRPZ
 +	rpz_end(repinfo);
@@ -3443,11 +3446,11 @@
 +#endif
  	if(repinfo->c->type == comm_udp)
  		return;
- 	reclaim_tcp_handler(repinfo->c);
-@@ -3063,6 +3081,9 @@
+ 	if(repinfo->c->tcp_req_info)
+@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
  {
- 	verbose(VERB_ALGO, "comm point start listening %d", 
- 		c->fd==-1?newfd:c->fd);
+ 	verbose(VERB_ALGO, "comm point start listening %d (%d msec)", 
+ 		c->fd==-1?newfd:c->fd, msec);
 +#ifdef ENABLE_FASTRPZ
 +	rpz_end(&c->repinfo);
 +#endif
@@ -3454,11 +3457,11 @@
  	if(c->type == comm_tcp_accept && !c->tcp_free) {
  		/* no use to start listening no free slots. */
  		return;
-Index: unboundfastrpz/util/netevent.h
-===================================================================
---- unboundfastrpz/util/netevent.h	(revision 4923)
-+++ unboundfastrpz/util/netevent.h	(working copy)
-@@ -120,6 +120,10 @@
+diff --git a/util/netevent.h b/util/netevent.h
+index d80c72b3..0233292f 100644
+--- a/util/netevent.h
++++ b/util/netevent.h
+@@ -120,6 +120,10 @@ struct comm_reply {
  	/** return type 0 (none), 4(IP4), 6(IP6) */
  	int srctype;
  	/* DnsCrypt context */
@@ -3469,11 +3472,11 @@
  #ifdef USE_DNSCRYPT
  	uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
  	uint8_t nmkey[crypto_box_BEFORENMBYTES];
-Index: unboundfastrpz/validator/validator.c
-===================================================================
---- unboundfastrpz/validator/validator.c	(revision 4923)
-+++ unboundfastrpz/validator/validator.c	(working copy)
-@@ -2755,6 +2755,12 @@
+diff --git a/validator/validator.c b/validator/validator.c
+index c3ca0a27..15251988 100644
+--- a/validator/validator.c
++++ b/validator/validator.c
+@@ -2761,6 +2761,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
  			default:
  				/* NSEC proof did not work, try next */
  				break;
@@ -3486,7 +3489,7 @@
  		}
  
  		sec = nsec3_prove_nods(qstate->env, ve, 
-@@ -2788,6 +2794,12 @@
+@@ -2794,6 +2800,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
  			default:
  				/* NSEC3 proof did not work */
  				break;
--- contrib/unbound/contrib/libunbound.pc.in.orig
+++ contrib/unbound/contrib/libunbound.pc.in
@@ -7,8 +7,8 @@
 Description: Library with validating, recursive, and caching DNS resolver
 URL: http://www.unbound.net
 Version: @PACKAGE_VERSION@
-Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@
-Requires.private: @PC_PY_DEPENDENCY@
-Libs: -L${libdir} -lunbound -lssl -lcrypto
+Requires: @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
+Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@
+Libs: -L${libdir} -lunbound
 Libs.private: @SSLLIB@ @LIBS@
-Cflags: -I${includedir} 
+Cflags: -I${includedir}
--- contrib/unbound/contrib/libunbound.so.conf.orig
+++ contrib/unbound/contrib/libunbound.so.conf
@@ -14,6 +14,7 @@
 int ub_ctx_get_option(ub_ctx*, string, +string*);
 int ub_ctx_config(ub_ctx*, string);
 int ub_ctx_set_fwd(ub_ctx*, string);
+int ub_ctx_set_tls(ub_ctx*, bool(int));
 int ub_ctx_set_stub(ub_ctx*, string, string, bool(int));
 int ub_ctx_resolvconf(ub_ctx*, string);
 int ub_ctx_hosts(ub_ctx*, string);
--- contrib/unbound/contrib/unbound-fuzzme.patch.orig
+++ contrib/unbound/contrib/unbound-fuzzme.patch
@@ -0,0 +1,148 @@
+>From cc9b927f8f29d989ddb8415fe6508a538546abca Mon Sep 17 00:00:00 2001
+From: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
+Date: Wed, 2 Jan 2019 22:52:51 -0800
+Subject: [PATCH] Add unbound-fuzzme.
+
+This is a small program that simply parses a packet provided on stdout,
+for the purposes of fuzzing.
+---
+ .gitignore                |  1 +
+ Makefile.in               | 22 ++++++++++++++++++++--
+ smallapp/unbound-fuzzme.c | 38 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 59 insertions(+), 2 deletions(-)
+ create mode 100644 smallapp/unbound-fuzzme.c
+
+diff --git a/.gitignore b/.gitignore
+index f4527fd8..6163f905 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -24,6 +24,7 @@
+ /unbound-checkconf
+ /unbound-control
+ /unbound-control-setup
++/unbound-fuzzme
+ /unbound-host
+ /unbound.h
+ /asynclook
+diff --git a/Makefile.in b/Makefile.in
+index af5b10f6..dacf1ab5 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -177,6 +177,10 @@ shm_main.lo remote.lo stats.lo unbound.lo \
+ worker.lo @WIN_DAEMON_OBJ@
+ DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
+ $(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
++FUZZME_SRC=smallapp/unbound-fuzzme.c
++FUZZME_OBJ=unbound-fuzzme.lo
++FUZZME_OBJ_LINK=$(FUZZME_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
++$(COMPAT_OBJ)
+ CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c
+ CHECKCONF_OBJ=unbound-checkconf.lo worker_cb.lo
+ CHECKCONF_OBJ_LINK=$(CHECKCONF_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
+@@ -252,6 +256,7 @@ RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \
+ 	rsrc_unbound_checkconf.o
+ 
+ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
++	$(FUZZME_SRC) \
+ 	$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \
+ 	$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
+ 	$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
+@@ -259,6 +264,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
+ 	$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\
+ 	$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
+ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
++	$(FUZZME_OBJ) \
+ 	$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
+ 	$(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
+ 	$(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
+@@ -274,7 +280,7 @@ LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFL
+ 
+ all:	$(COMMON_OBJ) $(ALLTARGET)
+ 
+-alltargets:	unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS) $(PYUNBOUND_TARGET)
++alltargets:	unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup unbound-fuzzme$(EXEEXT) $(WINAPPS) $(PYUNBOUND_TARGET)
+ 
+ # compat with BSD make, register suffix, and an implicit rule to actualise it.
+ .SUFFIXES: .lo
+@@ -325,6 +331,9 @@ libunbound.la:	$(LIBUNBOUND_OBJ_LINK)
+ unbound$(EXEEXT):	$(DAEMON_OBJ_LINK) libunbound.la
+ 	$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
+ 
++unbound-fuzzme$(EXEEXT):	$(FUZZME_OBJ_LINK) libunbound.la
++	$(LINK) -o $@ $(FUZZME_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
++
+ unbound-checkconf$(EXEEXT):	$(CHECKCONF_OBJ_LINK) libunbound.la
+ 	$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
+ 
+@@ -447,7 +456,7 @@ util/configparser.c util/configparser.h:  $(srcdir)/util/configparser.y
+ 
+ clean:
+ 	rm -f *.o *.d *.lo *~ tags
+-	rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
++	rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-fuzzme$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
+ 	rm -f $(ALL_SRC:.c=.lint)
+ 	rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
+ 	rm -rf autom4te.cache .libs build doc/html doc/xml
+@@ -1183,6 +1192,15 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
+  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+  $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
+  $(srcdir)/validator/val_neg.h
++unbound-fuzzme.lo unbound-fuzzme.o: $(srcdir)/smallapp/unbound-fuzzme.c \
++ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
++  $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
++ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
+ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
+  $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+   $(srcdir)/daemon/remote.h \
+diff --git a/smallapp/unbound-fuzzme.c b/smallapp/unbound-fuzzme.c
+new file mode 100644
+index 00000000..74ae5204
+--- /dev/null
++++ b/smallapp/unbound-fuzzme.c
+@@ -0,0 +1,38 @@
++/*
++ * unbound-fuzzme.c - parse a packet provided on stdin (for fuzzing).
++ *
++ */
++#include "config.h"
++#include "util/regional.h"
++#include "util/fptr_wlist.h"
++#include "sldns/sbuffer.h"
++
++#define SZ 10000
++
++int main() {
++	char buffer[SZ];
++	size_t n_read = fread(buffer, 1, SZ, stdin);
++	if (n_read == SZ) {
++		printf("input too big\n");
++		return 1;
++	}
++	sldns_buffer *pkt = sldns_buffer_new(n_read);
++	sldns_buffer_init_frm_data(pkt, buffer, n_read);
++
++	struct regional *region = regional_create();
++
++	struct msg_parse* prs;
++	struct edns_data edns;
++	prs = (struct msg_parse*)malloc(sizeof(struct msg_parse));
++	if(!prs) {
++		printf("out of memory on incoming message\n");
++		return 1;
++	}
++	memset(prs, 0, sizeof(*prs));
++	memset(&edns, 0, sizeof(edns));
++	sldns_buffer_set_position(pkt, 0);
++	if(parse_packet(pkt, prs, region) != LDNS_RCODE_NOERROR) {
++		printf("parse error\n");
++		return 1;
++	}
++}
+-- 
+2.17.1
+
--- contrib/unbound/contrib/unbound.init.orig
+++ contrib/unbound/contrib/unbound.init
@@ -39,13 +39,13 @@
     # setup root jail
     if [ -s /etc/localtime ]; then 
 	[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
-	if [ ! -e ${rootdir}/etc/localtime ] || /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
+	if [ ! -e ${rootdir}/etc/localtime ] || ! /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
 	    cp -fp /etc/localtime ${rootdir}/etc/localtime
 	fi;
     fi;
     if [ -s /etc/resolv.conf ]; then
 	[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
-	if [ ! -e ${rootdir}/etc/resolv.conf ] || /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
+	if [ ! -e ${rootdir}/etc/resolv.conf ] || ! /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
 	    cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf
 	fi;
     fi;
@@ -54,10 +54,10 @@
 	[ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log
 	mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
     fi;
-    if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
+    if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
 	[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
-	[ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random
-	mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
+	[ -e ${rootdir}/dev/urandom ] || touch ${rootdir}/dev/urandom
+	mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
     fi;
 
     # if not running, start it up here
@@ -78,8 +78,8 @@
     if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
 	umount ${rootdir}/dev/log >/dev/null 2>&1
     fi;
-    if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
-	umount ${rootdir}/dev/random >/dev/null 2>&1
+    if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
+	umount ${rootdir}/dev/urandom >/dev/null 2>&1
     fi;
     return $retval
 }
--- contrib/unbound/contrib/unbound.init_fedora.orig
+++ contrib/unbound/contrib/unbound.init_fedora
@@ -42,7 +42,7 @@
 	    cp -fp /etc/localtime ${rootdir}/etc/localtime
 	fi;
 	mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
-	mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
+	mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
 	mount --bind -n /var/run/unbound ${rootdir}/var/run/unbound >/dev/null 2>&1;
 
     # if not running, start it up here
@@ -58,7 +58,7 @@
     killproc -p $pidfile unbound
     retval=$?
     [ $retval -eq 0 ] && rm -f $lockfile
-    for mountfile in /dev/log /dev/random /etc/localtime /etc/resolv.conf /var/run/unbound
+    for mountfile in /dev/log /dev/urandom /etc/localtime /etc/resolv.conf /var/run/unbound
     do
     if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}''${mountfile}'' /proc/mounts; then
 	umount ${rootdir}$mountfile >/dev/null 2>&1
--- contrib/unbound/contrib/unbound.service.in.orig
+++ contrib/unbound/contrib/unbound.service.in
@@ -1,3 +1,44 @@
+; For further details about the directives used in this unit file, including
+; the below, please refer to systemd's official documentation, available at
+; https://www.freedesktop.org/software/systemd/man/systemd.exec.html.
+;
+;
+;   - `ProtectSystem=strict` implies we mount the entire file system hierarchy
+;     read-only for the processes invoked by the unit except for the API file
+;     system subtrees /dev, /proc and /sys (which are protected by
+;     PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=).
+;
+;   - `PrivateTmp=yes` secures access to temporary files of the process, and
+;     makes sharing between processes via /tmp or /var/tmp impossible.
+;
+;   - `ProtectHome=yes` makes the directories /home, /root, and /run/user
+;     inaccessible and empty for processes invoked by the unit.
+;
+;   - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies
+;     (accessible through /sys/fs/cgroup) read-only to all processes invoked by
+;     the unit. It also implies `MountAPIVFS=yes`.
+;
+;   - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the
+;     unit User and Group with read-write permissions (0755) as soon as the
+;     unit starts. This allows unbound to store its pidfile. The directory and
+;     its content are automatically removed by systemd when the unit stops.
+;
+;   - `NoNewPrivileges=yes` ensures that the service process and all its
+;     children can never gain new privileges through execve().
+;
+;   - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID
+;     (SUID) or set-group-ID (SGID) bits on files or directories will be denied.
+;
+;   - `RestrictRealTime=yes` ensures that any attempts to enable realtime
+;     scheduling in a process invoked by the unit will be denied.
+;
+;   - `RestrictNamespaces=yes` ensures that access to any kind of namespacing
+;     is prohibited.
+;
+;   - `LockPersonality=yes` locks down the personality system call so that the
+;     kernel execution domain may not be changed from the default.
+;
+;
 [Unit]
 Description=Validating, recursive, and caching DNS resolver
 Documentation=man:unbound(8)
@@ -9,11 +50,11 @@
 WantedBy=multi-user.target
 
 [Service]
-ExecReload=/bin/kill -HUP $MAINPID
-ExecStart=@UNBOUND_SBIN_DIR@/unbound
+ExecReload=+/bin/kill -HUP $MAINPID
+ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
 NotifyAccess=main
 Type=notify
-CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
 MemoryDenyWriteExecute=true
 NoNewPrivileges=true
 PrivateDevices=true
@@ -21,11 +62,23 @@
 ProtectHome=true
 ProtectControlGroups=true
 ProtectKernelModules=true
-ProtectKernelTunables=true
 ProtectSystem=strict
-ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
+RuntimeDirectory=unbound
+ConfigurationDirectory=unbound
+StateDirectory=unbound
 RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
 RestrictRealtime=true
 SystemCallArchitectures=native
 SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
+RestrictNamespaces=yes
+LockPersonality=yes
+RestrictSUIDSGID=yes
+ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@
 
+# Below rules are needed when chroot is enabled (usually it's enabled by default).
+# If chroot is disabled like chrooot: "" then they may be safely removed.
+TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro
+TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro
+BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify
+BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom
+BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log
--- contrib/unbound/contrib/unbound_munin_.orig
+++ contrib/unbound/contrib/unbound_munin_
@@ -242,6 +242,8 @@
 		p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE"
 		p_config "num.query.tcp" "TCP queries" "ABSOLUTE"
 		p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE"
+		p_config "num.query.tls" "TLS queries" "ABSOLUTE"
+		p_config "num.query.tls.resume" "TLS resumes" "ABSOLUTE"
 		p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE"
 		p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE"
 		p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE"
@@ -443,7 +445,8 @@
 	for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
 		sed -e 's/=.*//'` total.num.queries \
 		total.num.cachehits total.num.prefetch num.query.tcp \
-		num.query.tcpout num.query.ipv6 unwanted.queries \
+		num.query.tcpout num.query.tls num.query.tls.resume \
+		num.query.ipv6 unwanted.queries \
 		unwanted.replies; do
 		if grep "^"$x"=" $state >/dev/null 2>&1; then
 			print_value $x
--- contrib/unbound/contrib/unbound_portable.service.in.orig
+++ contrib/unbound/contrib/unbound_portable.service.in
@@ -0,0 +1,49 @@
+; This unit file is provided to run unbound as portable service.
+; https://systemd.io/PORTABLE_SERVICES/
+;
+; To use this unit file, please make sure you either compile unbound with the
+; following options:
+;
+;  - --with-chroot-dir=""
+;
+; Or put the following options in your unbound configuration file:
+;
+;  - chroot: ""
+;
+;
+[Unit]
+Description=Validating, recursive, and caching DNS resolver
+Documentation=man:unbound(8)
+After=network.target
+Before=network-online.target nss-lookup.target
+Wants=nss-lookup.target
+
+[Install]
+WantedBy=multi-user.target
+
+[Service]
+ExecReload=+/bin/kill -HUP $MAINPID
+ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
+NotifyAccess=main
+Type=notify
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
+MemoryDenyWriteExecute=true
+NoNewPrivileges=true
+PrivateDevices=true
+PrivateTmp=true
+ProtectHome=true
+ProtectControlGroups=true
+ProtectKernelModules=true
+ProtectSystem=strict
+RuntimeDirectory=unbound
+ConfigurationDirectory=unbound
+StateDirectory=unbound
+RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
+RestrictRealtime=true
+SystemCallArchitectures=native
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
+RestrictNamespaces=yes
+LockPersonality=yes
+RestrictSUIDSGID=yes
+BindPaths=/run/systemd/notify
+BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout
--- contrib/unbound/daemon/daemon.c.orig
+++ contrib/unbound/daemon/daemon.c
@@ -221,7 +221,9 @@
 	(void)sldns_key_EVP_load_gost_id();
 #  endif
 #  if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
+#    ifndef S_SPLINT_S
 	OpenSSL_add_all_algorithms();
+#    endif
 #  else
 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
 		| OPENSSL_INIT_ADD_ALL_DIGESTS
@@ -248,8 +250,6 @@
 	/* init timezone info while we are not chrooted yet */
 	tzset();
 #endif
-	/* open /dev/random if needed */
-	ub_systemseed((unsigned)time(NULL)^(unsigned)getpid()^0xe67);
 	daemon->need_to_exit = 0;
 	modstack_init(&daemon->mods);
 	if(!(daemon->env = (struct module_env*)calloc(1, 
@@ -427,9 +427,7 @@
 	int* shufport;
 	log_assert(daemon && daemon->cfg);
 	if(!daemon->rand) {
-		unsigned int seed = (unsigned int)time(NULL) ^ 
-			(unsigned int)getpid() ^ 0x438;
-		daemon->rand = ub_initstate(seed, NULL);
+		daemon->rand = ub_initstate(NULL);
 		if(!daemon->rand)
 			fatal_exit("could not init random generator");
 		hash_set_raninit((uint32_t)ub_random(daemon->rand));
@@ -575,6 +573,9 @@
 daemon_fork(struct daemon* daemon)
 {
 	int have_view_respip_cfg = 0;
+#ifdef HAVE_SYSTEMD
+	int ret;
+#endif
 
 	log_assert(daemon);
 	if(!(daemon->views = views_create()))
@@ -616,7 +617,8 @@
 		have_view_respip_cfg;
 	
 	/* read auth zonefiles */
-	if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1))
+	if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
+		&daemon->use_rpz))
 		fatal_exit("auth_zones could not be setup");
 
 	/* setup modules */
@@ -628,6 +630,12 @@
 	if(daemon->use_response_ip &&
 		modstack_find(&daemon->mods, "respip") < 0)
 		fatal_exit("response-ip options require respip module");
+	/* RPZ response ip triggers don't work as expected without the respip
+	 * module.  To avoid run-time operational surprise we reject such
+	 * configuration. */
+	if(daemon->use_rpz &&
+		modstack_find(&daemon->mods, "respip") < 0)
+		fatal_exit("RPZ requires the respip module");
 
 	/* first create all the worker structures, so we can pass
 	 * them to the newly created threads. 
@@ -660,7 +668,12 @@
 
 	/* Start resolver service on main thread. */
 #ifdef HAVE_SYSTEMD
-	sd_notify(0, "READY=1");
+	ret = sd_notify(0, "READY=1");
+	if(ret <= 0 && getenv("NOTIFY_SOCKET"))
+		fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
+				"access/permission to use the socket presented by systemd.",
+				getenv("NOTIFY_SOCKET"),
+				(ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
 #endif
 	log_info("start of service (%s).", PACKAGE_STRING);
 	worker_work(daemon->workers[0]);
@@ -749,6 +762,7 @@
 	free(daemon->pidfile);
 	free(daemon->env);
 #ifdef HAVE_SSL
+	listen_sslctx_delete_ticket_keys();
 	SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
 	SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
 #endif
@@ -769,7 +783,7 @@
 #  endif
 #  ifdef HAVE_OPENSSL_CONFIG
 	EVP_cleanup();
-#  if OPENSSL_VERSION_NUMBER < 0x10100000
+#  if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE)
 	ENGINE_cleanup();
 #  endif
 	CONF_modules_free();
--- contrib/unbound/daemon/daemon.h.orig
+++ contrib/unbound/daemon/daemon.h
@@ -132,6 +132,8 @@
 	struct respip_set* respip_set;
 	/** some response-ip tags or actions are configured if true */
 	int use_response_ip;
+	/** some RPZ policies are configured */
+	int use_rpz;
 #ifdef USE_DNSCRYPT
 	/** the dnscrypt environment */
 	struct dnsc_env* dnscenv;
--- contrib/unbound/daemon/remote.c.orig
+++ contrib/unbound/daemon/remote.c
@@ -69,6 +69,7 @@
 #include "services/mesh.h"
 #include "services/localzone.h"
 #include "services/authzone.h"
+#include "services/rpz.h"
 #include "util/storage/slabhash.h"
 #include "util/fptr_wlist.h"
 #include "util/data/dname.h"
@@ -499,7 +500,7 @@
 			goto close_exit;
 		}
 		SSL_set_accept_state(n->ssl);
-		(void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY);
+		(void)SSL_set_mode(n->ssl, (long)SSL_MODE_AUTO_RETRY);
 		if(!SSL_set_fd(n->ssl, newfd)) {
 			log_crypto_err("could not SSL_set_fd");
 			SSL_free(n->ssl);
@@ -674,19 +675,19 @@
 
 /** do the stop command */
 static void
-do_stop(RES* ssl, struct daemon_remote* rc)
+do_stop(RES* ssl, struct worker* worker)
 {
-	rc->worker->need_to_exit = 1;
-	comm_base_exit(rc->worker->base);
+	worker->need_to_exit = 1;
+	comm_base_exit(worker->base);
 	send_ok(ssl);
 }
 
 /** do the reload command */
 static void
-do_reload(RES* ssl, struct daemon_remote* rc)
+do_reload(RES* ssl, struct worker* worker)
 {
-	rc->worker->need_to_exit = 0;
-	comm_base_exit(rc->worker->base);
+	worker->need_to_exit = 0;
+	comm_base_exit(worker->base);
 	send_ok(ssl);
 }
 
@@ -719,8 +720,8 @@
 		(unsigned long)s->svr.num_queries_missed_cache)) return 0;
 	if(!ssl_printf(ssl, "%s.num.prefetch"SQ"%lu\n", nm, 
 		(unsigned long)s->svr.num_queries_prefetch)) return 0;
-	if(!ssl_printf(ssl, "%s.num.zero_ttl"SQ"%lu\n", nm,
-		(unsigned long)s->svr.zero_ttl_responses)) return 0;
+	if(!ssl_printf(ssl, "%s.num.expired"SQ"%lu\n", nm,
+		(unsigned long)s->svr.ans_expired)) return 0;
 	if(!ssl_printf(ssl, "%s.num.recursivereplies"SQ"%lu\n", nm, 
 		(unsigned long)s->mesh_replies_sent)) return 0;
 #ifdef USE_DNSCRYPT
@@ -789,7 +790,8 @@
 
 /** print mem stats */
 static int
-print_mem(RES* ssl, struct worker* worker, struct daemon* daemon)
+print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
+	struct ub_stats_info* s)
 {
 	size_t msg, rrset, val, iter, respip;
 #ifdef CLIENT_SUBNET
@@ -847,6 +849,9 @@
 			dnscrypt_nonce))
 		return 0;
 #endif /* USE_DNSCRYPT */
+	if(!print_longnum(ssl, "mem.streamwait"SQ,
+		(size_t)s->svr.mem_stream_wait))
+		return 0;
 	return 1;
 }
 
@@ -969,6 +974,8 @@
 		(unsigned long)s->svr.qtcp_outgoing)) return 0;
 	if(!ssl_printf(ssl, "num.query.tls"SQ"%lu\n", 
 		(unsigned long)s->svr.qtls)) return 0;
+	if(!ssl_printf(ssl, "num.query.tls.resume"SQ"%lu\n", 
+		(unsigned long)s->svr.qtls_resume)) return 0;
 	if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n", 
 		(unsigned long)s->svr.qipv6)) return 0;
 	/* flags */
@@ -1039,6 +1046,16 @@
 		(unsigned)s->svr.infra_cache_count)) return 0;
 	if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n",
 		(unsigned)s->svr.key_cache_count)) return 0;
+	/* applied RPZ actions */
+	for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
+		if(i == RPZ_NO_OVERRIDE_ACTION)
+			continue;
+		if(inhibit_zero && s->svr.rpz_action[i] == 0)
+			continue;
+		if(!ssl_printf(ssl, "num.rpz.action.%s"SQ"%lu\n",
+			rpz_action_to_string(i),
+			(unsigned long)s->svr.rpz_action[i])) return 0;
+	}
 #ifdef USE_DNSCRYPT
 	if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n",
 		(unsigned)s->svr.shared_secret_cache_count)) return 0;
@@ -1064,9 +1081,9 @@
 
 /** do the stats command */
 static void
-do_stats(RES* ssl, struct daemon_remote* rc, int reset)
+do_stats(RES* ssl, struct worker* worker, int reset)
 {
-	struct daemon* daemon = rc->worker->daemon;
+	struct daemon* daemon = worker->daemon;
 	struct ub_stats_info total;
 	struct ub_stats_info s;
 	int i;
@@ -1074,7 +1091,7 @@
 	log_assert(daemon->num > 0);
 	/* gather all thread statistics in one place */
 	for(i=0; i<daemon->num; i++) {
-		server_stats_obtain(rc->worker, daemon->workers[i], &s, reset);
+		server_stats_obtain(worker, daemon->workers[i], &s, reset);
 		if(!print_thread_stats(ssl, i, &s))
 			return;
 		if(i == 0)
@@ -1085,10 +1102,10 @@
 	total.mesh_time_median /= (double)daemon->num;
 	if(!print_stats(ssl, "total", &total)) 
 		return;
-	if(!print_uptime(ssl, rc->worker, reset))
+	if(!print_uptime(ssl, worker, reset))
 		return;
 	if(daemon->cfg->stat_extended) {
-		if(!print_mem(ssl, rc->worker, daemon)) 
+		if(!print_mem(ssl, worker, daemon, &total))
 			return;
 		if(!print_hist(ssl, &total))
 			return;
@@ -1428,6 +1445,28 @@
 	lock_rw_unlock(&v->lock);
 }
 
+/** Add new RR data from stdin to view */
+static void
+do_view_datas_add(RES* ssl, struct worker* worker, char* arg)
+{
+	struct view* v;
+	v = views_find_view(worker->daemon->views,
+		arg, 1 /* get write lock*/);
+	if(!v) {
+		ssl_printf(ssl,"no view with name: %s\n", arg);
+		return;
+	}
+	if(!v->local_zones) {
+		if(!(v->local_zones = local_zones_create())){
+			lock_rw_unlock(&v->lock);
+			ssl_printf(ssl,"error out of memory\n");
+			return;
+		}
+	}
+	do_datas_add(ssl, v->local_zones);
+	lock_rw_unlock(&v->lock);
+}
+
 /** Remove RR data from view */
 static void
 do_view_data_remove(RES* ssl, struct worker* worker, char* arg)
@@ -1451,6 +1490,27 @@
 	lock_rw_unlock(&v->lock);
 }
 
+/** Remove RR data from stdin from view */
+static void
+do_view_datas_remove(RES* ssl, struct worker* worker, char* arg)
+{
+	struct view* v;
+	v = views_find_view(worker->daemon->views,
+		arg, 1 /* get write lock*/);
+	if(!v) {
+		ssl_printf(ssl,"no view with name: %s\n", arg);
+		return;
+	}
+	if(!v->local_zones){
+		lock_rw_unlock(&v->lock);
+		ssl_printf(ssl, "removed 0 datas\n");
+		return;
+	}
+
+	do_datas_remove(ssl, v->local_zones);
+	lock_rw_unlock(&v->lock);
+}
+
 /** cache lookup of nameservers */
 static void
 do_lookup(RES* ssl, struct worker* worker, char* arg)
@@ -1959,7 +2019,7 @@
 				return NULL;
 			}
 		} else {
-#ifndef HAVE_SSL_SET1_HOST
+#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
 			if(auth_name)
 			  log_err("no name verification functionality in "
 				"ssl library, ignored name for %s", todo);
@@ -2456,7 +2516,7 @@
 		(void)ssl_printf(ssl, "error no auth-zone %s\n", arg);
 		return;
 	}
-	if(!auth_zone_read_zonefile(z)) {
+	if(!auth_zone_read_zonefile(z, worker->env.cfg)) {
 		lock_rw_unlock(&z->lock);
 		(void)ssl_printf(ssl, "error failed to read %s\n", arg);
 		return;
@@ -2478,8 +2538,10 @@
 	if(!az || !auth_zones_startprobesequence(az, &worker->env, nm, nmlen,
 		LDNS_RR_CLASS_IN)) {
 		(void)ssl_printf(ssl, "error zone xfr task not found %s\n", arg);
+		free(nm);
 		return;
 	}
+	free(nm);
 	send_ok(ssl);
 }
 	
@@ -2823,16 +2885,16 @@
 	char* p = skipwhite(cmd);
 	/* compare command */
 	if(cmdcmp(p, "stop", 4)) {
-		do_stop(ssl, rc);
+		do_stop(ssl, worker);
 		return;
 	} else if(cmdcmp(p, "reload", 6)) {
-		do_reload(ssl, rc);
+		do_reload(ssl, worker);
 		return;
 	} else if(cmdcmp(p, "stats_noreset", 13)) {
-		do_stats(ssl, rc, 0);
+		do_stats(ssl, worker, 0);
 		return;
 	} else if(cmdcmp(p, "stats", 5)) {
-		do_stats(ssl, rc, 1);
+		do_stats(ssl, worker, 1);
 		return;
 	} else if(cmdcmp(p, "status", 6)) {
 		do_status(ssl, worker);
@@ -2961,8 +3023,12 @@
 		do_view_zone_add(ssl, worker, skipwhite(p+15));
 	} else if(cmdcmp(p, "view_local_data_remove", 22)) {
 		do_view_data_remove(ssl, worker, skipwhite(p+22));
+	} else if(cmdcmp(p, "view_local_datas_remove", 23)){
+		do_view_datas_remove(ssl, worker, skipwhite(p+23));
 	} else if(cmdcmp(p, "view_local_data", 15)) {
 		do_view_data_add(ssl, worker, skipwhite(p+15));
+	} else if(cmdcmp(p, "view_local_datas", 16)) {
+		do_view_datas_add(ssl, worker, skipwhite(p+16));
 	} else if(cmdcmp(p, "flush_zone", 10)) {
 		do_flush_zone(ssl, worker, skipwhite(p+10));
 	} else if(cmdcmp(p, "flush_type", 10)) {
@@ -3095,7 +3161,7 @@
 	} else {
 		if(r == 0)
 			log_err("remote control connection closed prematurely");
-		log_addr(1, "failed connection from",
+		log_addr(VERB_OPS, "failed connection from",
 			&s->c->repinfo.addr, s->c->repinfo.addrlen);
 		log_crypto_err("remote control failed ssl");
 		clean_point(rc, s);
--- contrib/unbound/daemon/stats.c.orig
+++ contrib/unbound/daemon/stats.c
@@ -66,6 +66,9 @@
 #ifdef CLIENT_SUBNET
 #include "edns-subnet/subnetmod.h"
 #endif
+#ifdef HAVE_SSL
+#include <openssl/ssl.h>
+#endif
 
 /** add timers and the values do not overflow or become negative */
 static void
@@ -74,7 +77,7 @@
 #ifndef S_SPLINT_S
 	(*d_sec) += add_sec;
 	(*d_usec) += add_usec;
-	if((*d_usec) > 1000000) {
+	if((*d_usec) >= 1000000) {
 		(*d_usec) -= 1000000;
 		(*d_sec)++;
 	}
@@ -268,8 +271,10 @@
 	s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
 	s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
 	s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
-	for(i=0; i<16; i++)
+	for(i=0; i<UB_STATS_RCODE_NUM; i++)
 		s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
+	for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
+		s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i];
 	timehist_export(worker->env.mesh->histogram, s->svr.hist, 
 		NUM_BUCKETS_HIST);
 	/* values from outside network */
@@ -328,6 +333,8 @@
 		}
 		lock_rw_unlock(&worker->env.auth_zones->lock);
 	}
+	s->svr.mem_stream_wait =
+		(long long)tcp_req_info_get_stream_buffer_size();
 
 	/* Set neg cache usage numbers */
 	set_neg_cache_stats(worker, &s->svr, reset);
@@ -393,6 +400,7 @@
 	total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
 	total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
 	total->svr.sum_query_list_size += a->svr.sum_query_list_size;
+	total->svr.ans_expired += a->svr.ans_expired;
 #ifdef USE_DNSCRYPT
 	total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted;
 	total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert;
@@ -412,6 +420,7 @@
 		total->svr.qtcp += a->svr.qtcp;
 		total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
 		total->svr.qtls += a->svr.qtls;
+		total->svr.qtls_resume += a->svr.qtls_resume;
 		total->svr.qipv6 += a->svr.qipv6;
 		total->svr.qbit_QR += a->svr.qbit_QR;
 		total->svr.qbit_AA += a->svr.qbit_AA;
@@ -424,7 +433,6 @@
 		total->svr.qEDNS += a->svr.qEDNS;
 		total->svr.qEDNS_DO += a->svr.qEDNS_DO;
 		total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
-		total->svr.zero_ttl_responses += a->svr.zero_ttl_responses;
 		total->svr.ans_secure += a->svr.ans_secure;
 		total->svr.ans_bogus += a->svr.ans_bogus;
 		total->svr.unwanted_replies += a->svr.unwanted_replies;
@@ -440,6 +448,8 @@
 			total->svr.ans_rcode[i] += a->svr.ans_rcode[i];
 		for(i=0; i<NUM_BUCKETS_HIST; i++)
 			total->svr.hist[i] += a->svr.hist[i];
+		for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
+			total->svr.rpz_action[i] += a->svr.rpz_action[i];
 	}
 
 	total->mesh_num_states += a->mesh_num_states;
@@ -468,8 +478,13 @@
 	stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
 	if(c->type != comm_udp) {
 		stats->qtcp++;
-		if(c->ssl != NULL)
+		if(c->ssl != NULL) {
 			stats->qtls++;
+#ifdef HAVE_SSL
+			if(SSL_session_reused(c->ssl)) 
+				stats->qtls_resume++;
+#endif
+		}
 	}
 	if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
 		stats->qipv6++;
--- contrib/unbound/daemon/unbound.c.orig
+++ contrib/unbound/daemon/unbound.c
@@ -67,6 +67,7 @@
 #ifdef HAVE_GRP_H
 #include <grp.h>
 #endif
+#include <openssl/ssl.h>
 
 #ifndef S_SPLINT_S
 /* splint chokes on this system header file */
@@ -87,8 +88,9 @@
 #  include "nss.h"
 #endif
 
-/** print usage. */
-static void usage(void)
+/** print build options. */
+static void
+print_build_options(void)
 {
 	const char** m;
 	const char *evnm="event", *evsys="", *evmethod="";
@@ -95,23 +97,11 @@
 	time_t t;
 	struct timeval now;
 	struct ub_event_base* base;
-	printf("usage:  local-unbound [options]\n");
-	printf("	start unbound daemon DNS resolver.\n");
-	printf("-h	this help\n");
-	printf("-c file	config file to read instead of %s\n", CONFIGFILE);
-	printf("	file format is described in unbound.conf(5).\n");
-	printf("-d	do not fork into the background.\n");
-	printf("-p	do not create a pidfile.\n");
-	printf("-v	verbose (more times to increase verbosity)\n");
-#ifdef UB_ON_WINDOWS
-	printf("-w opt	windows option: \n");
-	printf("   	install, remove - manage the services entry\n");
-	printf("   	service - used to start from services control panel\n");
-#endif
-	printf("Version %s\n", PACKAGE_VERSION);
+	printf("Version %s\n\n", PACKAGE_VERSION);
+	printf("Configure line: %s\n", CONFCMDLINE);
 	base = ub_default_event_base(0,&t,&now);
 	ub_get_event_sys(base, &evnm, &evsys, &evmethod);
-	printf("linked libs: %s %s (it uses %s), %s\n", 
+	printf("Linked libs: %s %s (it uses %s), %s\n",
 		evnm, evsys, evmethod,
 #ifdef HAVE_SSL
 #  ifdef SSLEAY_VERSION
@@ -125,7 +115,7 @@
 		"nettle"
 #endif
 		);
-	printf("linked modules:");
+	printf("Linked modules:");
 	for(m = module_list_avail(); *m; m++)
 		printf(" %s", *m);
 	printf("\n");
@@ -132,9 +122,35 @@
 #ifdef USE_DNSCRYPT
 	printf("DNSCrypt feature available\n");
 #endif
+#ifdef USE_TCP_FASTOPEN
+	printf("TCP Fastopen feature available\n");
+#endif
+	ub_event_base_free(base);
+	printf("\nBSD licensed, see LICENSE in source package for details.\n");
+	printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
+}
+
+/** print usage. */
+static void
+usage(void)
+{
+	printf("usage:  unbound [options]\n");
+	printf("	start unbound daemon DNS resolver.\n");
+	printf("-h	this help.\n");
+	printf("-c file	config file to read instead of %s\n", CONFIGFILE);
+	printf("	file format is described in unbound.conf(5).\n");
+	printf("-d	do not fork into the background.\n");
+	printf("-p	do not create a pidfile.\n");
+	printf("-v	verbose (more times to increase verbosity).\n");
+	printf("-V	show version number and build options.\n");
+#ifdef UB_ON_WINDOWS
+	printf("-w opt	windows option: \n");
+	printf("   	install, remove - manage the services entry\n");
+	printf("   	service - used to start from services control panel\n");
+#endif
+	printf("\nVersion %s\n", PACKAGE_VERSION);
 	printf("BSD licensed, see LICENSE in source package for details.\n");
 	printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
-	ub_event_base_free(base);
 }
 
 #ifndef unbound_testbound
@@ -243,21 +259,10 @@
 #endif /* S_SPLINT_S */
 }
 
-/** set default logfile identity based on value from argv[0] at startup **/
-static void
-log_ident_set_fromdefault(struct config_file* cfg,
-	const char *log_default_identity)
-{
-	if(cfg->log_identity == NULL || cfg->log_identity[0] == 0)
-		log_ident_set(log_default_identity);
-	else
-		log_ident_set(cfg->log_identity);
-}
-
 /** set verbosity, check rlimits, cache settings */
 static void
-apply_settings(struct daemon* daemon, struct config_file* cfg, 
-	int cmdline_verbose, int debug_mode, const char* log_default_identity)
+apply_settings(struct daemon* daemon, struct config_file* cfg,
+	int cmdline_verbose, int debug_mode)
 {
 	/* apply if they have changed */
 	verbosity = cmdline_verbose + cfg->verbosity;
@@ -273,7 +278,7 @@
 		log_warn("use-systemd and do-daemonize should not be enabled at the same time");
 	}
 
-	log_ident_set_fromdefault(cfg, log_default_identity);
+	log_ident_set_or_default(cfg->log_identity);
 }
 
 #ifdef HAVE_KILL
@@ -430,6 +435,24 @@
 		if(!(daemon->listen_sslctx = listen_sslctx_create(
 			cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
 			fatal_exit("could not set up listen SSL_CTX");
+		if(cfg->tls_ciphers && cfg->tls_ciphers[0]) {
+			if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) {
+				fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers);
+			}
+		}
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
+		if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) {
+			if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) {
+				fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites);
+			}
+		}
+#endif
+		if(cfg->tls_session_ticket_keys.first &&
+			cfg->tls_session_ticket_keys.first->str[0] != 0) {
+			if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) {
+				fatal_exit("could not set session ticket SSL_CTX");
+			}
+		}
 	}
 	if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
 		cfg->tls_cert_bundle, cfg->tls_win_cert)))
@@ -605,11 +628,10 @@
  * @param cmdline_verbose: verbosity resulting from commandline -v.
  *    These increase verbosity as specified in the config file.
  * @param debug_mode: if set, do not daemonize.
- * @param log_default_identity: Default identity to report in logs
  * @param need_pidfile: if false, no pidfile is checked or created.
  */
 static void 
-run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity, int need_pidfile)
+run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pidfile)
 {
 	struct config_file* cfg = NULL;
 	struct daemon* daemon = NULL;
@@ -633,7 +655,7 @@
 					"or unbound-checkconf", cfgfile);
 			log_warn("Continuing with default config settings");
 		}
-		apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
+		apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
 		if(!done_setup)
 			config_lookup_uid(cfg);
 	
@@ -699,9 +721,10 @@
 
 	log_init(NULL, 0, NULL);
 	log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
+	log_ident_set_default(log_ident_default);
 	log_ident_set(log_ident_default);
 	/* parse the options */
-	while( (c=getopt(argc, argv, "c:dhpvw:")) != -1) {
+	while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) {
 		switch(c) {
 		case 'c':
 			cfgfile = optarg;
@@ -722,6 +745,9 @@
 		case 'w':
 			winopt = optarg;
 			break;
+		case 'V':
+			print_build_options();
+			return 0;
 		case '?':
 		case 'h':
 		default:
@@ -746,11 +772,11 @@
 		return 1;
 	}
 
-	run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile);
+	run_daemon(cfgfile, cmdline_verbose, debug_mode, need_pidfile);
 	log_init(NULL, 0, NULL); /* close logfile */
 #ifndef unbound_testbound
 	if(log_get_lock()) {
-		lock_quick_destroy((lock_quick_type*)log_get_lock());
+		lock_basic_destroy((lock_basic_type*)log_get_lock());
 	}
 #endif
 	return 0;
--- contrib/unbound/daemon/worker.c.orig
+++ contrib/unbound/daemon/worker.c
@@ -61,6 +61,7 @@
 #include "services/authzone.h"
 #include "services/mesh.h"
 #include "services/localzone.h"
+#include "services/rpz.h"
 #include "util/data/msgparse.h"
 #include "util/data/msgencode.h"
 #include "util/data/dname.h"
@@ -572,9 +573,10 @@
 apply_respip_action(struct worker* worker, const struct query_info* qinfo,
 	struct respip_client_info* cinfo, struct reply_info* rep,
 	struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
-	struct reply_info** encode_repp)
+	struct reply_info** encode_repp, struct auth_zones* az)
 {
-	struct respip_action_info actinfo = {respip_none, NULL};
+	struct respip_action_info actinfo = {0};
+	actinfo.action = respip_none;
 
 	if(qinfo->qtype != LDNS_RR_TYPE_A &&
 		qinfo->qtype != LDNS_RR_TYPE_AAAA &&
@@ -582,7 +584,7 @@
 		return 1;
 
 	if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
-		alias_rrset, 0, worker->scratchpad))
+		alias_rrset, 0, worker->scratchpad, az))
 		return 0;
 
 	/* xxx_deny actions mean dropping the reply, unless the original reply
@@ -595,9 +597,19 @@
 	/* If address info is returned, it means the action should be an
 	 * 'inform' variant and the information should be logged. */
 	if(actinfo.addrinfo) {
-		respip_inform_print(actinfo.addrinfo, qinfo->qname,
+		respip_inform_print(&actinfo, qinfo->qname,
 			qinfo->qtype, qinfo->qclass, qinfo->local_alias,
 			repinfo);
+
+		if(worker->stats.extended && actinfo.rpz_used) {
+			if(actinfo.rpz_disabled)
+				worker->stats.rpz_action[RPZ_DISABLED_ACTION]++;
+			if(actinfo.rpz_cname_override)
+				worker->stats.rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
+			else
+				worker->stats.rpz_action[
+					respip_action_to_rpz_action(actinfo.action)]++;
+		}
 	}
 
 	return 1;
@@ -613,10 +625,10 @@
  * be completely dropped, '*need_drop' will be set to 1. */
 static int
 answer_from_cache(struct worker* worker, struct query_info* qinfo,
-	struct respip_client_info* cinfo, int* need_drop,
-	struct ub_packed_rrset_key** alias_rrset,
+	struct respip_client_info* cinfo, int* need_drop, int* is_expired_answer,
+	int* is_secure_answer, struct ub_packed_rrset_key** alias_rrset,
 	struct reply_info** partial_repp,
-	struct reply_info* rep, uint16_t id, uint16_t flags, 
+	struct reply_info* rep, uint16_t id, uint16_t flags,
 	struct comm_reply* repinfo, struct edns_data* edns)
 {
 	struct edns_data edns_bak;
@@ -624,46 +636,42 @@
 	uint16_t udpsize = edns->udp_size;
 	struct reply_info* encode_rep = rep;
 	struct reply_info* partial_rep = *partial_repp;
-	int secure;
 	int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
 		&& worker->env.need_to_validate;
-	*partial_repp = NULL;	/* avoid accidental further pass */
-	if(worker->env.cfg->serve_expired) {
-		if(worker->env.cfg->serve_expired_ttl &&
-			rep->serve_expired_ttl < timenow)
-			return 0;
-		if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
-			return 0;
-		/* below, rrsets with ttl before timenow become TTL 0 in
-		 * the response */
-		/* This response was served with zero TTL */
-		if (timenow >= rep->ttl) {
-			worker->stats.zero_ttl_responses++;
-		}
-	} else {
-		/* see if it is possible */
-		if(rep->ttl < timenow) {
+	*partial_repp = NULL;  /* avoid accidental further pass */
+
+	/* Check TTL */
+	if(rep->ttl < timenow) {
+		/* Check if we need to serve expired now */
+		if(worker->env.cfg->serve_expired &&
+			!worker->env.cfg->serve_expired_client_timeout) {
+				if(worker->env.cfg->serve_expired_ttl &&
+					rep->serve_expired_ttl < timenow)
+					return 0;
+				if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
+					return 0;
+				*is_expired_answer = 1;
+		} else {
 			/* the rrsets may have been updated in the meantime.
 			 * we will refetch the message format from the
-			 * authoritative server 
+			 * authoritative server
 			 */
 			return 0;
 		}
+	} else {
 		if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
 			return 0;
-		/* locked and ids and ttls are OK. */
 	}
+	/* locked and ids and ttls are OK. */
+
 	/* check CNAME chain (if any) */
-	if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type == 
-		htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type == 
+	if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
+		htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
 		htons(LDNS_RR_TYPE_DNAME))) {
 		if(!reply_check_cname_chain(qinfo, rep)) {
 			/* cname chain invalid, redo iterator steps */
 			verbose(VERB_ALGO, "Cache reply: cname chain broken");
-		bail_out:
-			rrset_array_unlock_touch(worker->env.rrset_cache, 
-				worker->scratchpad, rep->ref, rep->rrset_count);
-			return 0;
+			goto bail_out;
 		}
 	}
 	/* check security status of the cached answer */
@@ -677,9 +685,9 @@
 		if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
 			LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
 			goto bail_out;
-		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, 
+		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
 			qinfo, id, flags, edns);
-		rrset_array_unlock_touch(worker->env.rrset_cache, 
+		rrset_array_unlock_touch(worker->env.rrset_cache,
 			worker->scratchpad, rep->ref, rep->rrset_count);
 		if(worker->stats.extended) {
 			worker->stats.ans_bogus ++;
@@ -686,22 +694,22 @@
 			worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL] ++;
 		}
 		return 1;
-	} else if( rep->security == sec_status_unchecked && must_validate) {
+	} else if(rep->security == sec_status_unchecked && must_validate) {
 		verbose(VERB_ALGO, "Cache reply: unchecked entry needs "
 			"validation");
 		goto bail_out; /* need to validate cache entry first */
 	} else if(rep->security == sec_status_secure) {
-		if(reply_all_rrsets_secure(rep))
-			secure = 1;
-		else	{
+		if(reply_all_rrsets_secure(rep)) {
+			*is_secure_answer = 1;
+		} else {
 			if(must_validate) {
 				verbose(VERB_ALGO, "Cache reply: secure entry"
 					" changed status");
 				goto bail_out; /* rrset changed, re-verify */
 			}
-			secure = 0;
+			*is_secure_answer = 0;
 		}
-	} else	secure = 0;
+	} else *is_secure_answer = 0;
 
 	edns_bak = *edns;
 	edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -712,20 +720,22 @@
 		(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
 		goto bail_out;
 	*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
-	if(worker->daemon->use_response_ip && !partial_rep &&
-	   !apply_respip_action(worker, qinfo, cinfo, rep, repinfo, alias_rrset,
-			&encode_rep)) {
+	if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
+		!partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep,
+		repinfo, alias_rrset,
+		&encode_rep, worker->env.auth_zones)) {
 		goto bail_out;
 	} else if(partial_rep &&
 		!respip_merge_cname(partial_rep, qinfo, rep, cinfo,
-		must_validate, &encode_rep, worker->scratchpad)) {
+		must_validate, &encode_rep, worker->scratchpad,
+		worker->env.auth_zones)) {
 		goto bail_out;
 	}
-	if(encode_rep != rep)
-		secure = 0; /* if rewritten, it can't be considered "secure" */
+	if(encode_rep != rep) {
+		/* if rewritten, it can't be considered "secure" */
+		*is_secure_answer = 0;
+	}
 	if(!encode_rep || *alias_rrset) {
-		sldns_buffer_clear(repinfo->c->buffer);
-		sldns_buffer_flip(repinfo->c->buffer);
 		if(!encode_rep)
 			*need_drop = 1;
 		else {
@@ -741,7 +751,7 @@
 		repinfo->c, worker->scratchpad) ||
 		!reply_info_answer_encode(qinfo, encode_rep, id, flags,
 		repinfo->c->buffer, timenow, 1, worker->scratchpad,
-		udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
+		udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) {
 		if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
 			LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
 				edns->opt_list = NULL;
@@ -752,26 +762,30 @@
 	 * is bad while holding locks. */
 	rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad,
 		rep->ref, rep->rrset_count);
-	if(worker->stats.extended) {
-		if(secure) worker->stats.ans_secure++;
-		server_stats_insrcode(&worker->stats, repinfo->c->buffer);
-	}
 	/* go and return this buffer to the client */
 	return 1;
+
+bail_out:
+	rrset_array_unlock_touch(worker->env.rrset_cache, 
+		worker->scratchpad, rep->ref, rep->rrset_count);
+	return 0;
 }
 
-/** Reply to client and perform prefetch to keep cache up to date.
- * If the buffer for the reply is empty, it indicates that only prefetch is
- * necessary and the reply should be suppressed (because it's dropped or
- * being deferred). */
+/** Reply to client and perform prefetch to keep cache up to date. */
 static void
 reply_and_prefetch(struct worker* worker, struct query_info* qinfo, 
-	uint16_t flags, struct comm_reply* repinfo, time_t leeway)
+	uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply)
 {
 	/* first send answer to client to keep its latency 
 	 * as small as a cachereply */
-	if(sldns_buffer_limit(repinfo->c->buffer) != 0)
+	if(!noreply) {
+		if(repinfo->c->tcp_req_info) {
+			sldns_buffer_copy(
+				repinfo->c->tcp_req_info->spool_buffer,
+				repinfo->c->buffer);
+		}
 		comm_point_send_reply(repinfo);
+	}
 	server_stats_prefetch(&worker->stats, worker);
 	
 	/* create the prefetch in the mesh as a normal lookup without
@@ -1082,6 +1096,8 @@
 	struct acl_addr* acladdr;
 	int rc = 0;
 	int need_drop = 0;
+	int is_expired_answer = 0;
+	int is_secure_answer = 0;
 	/* We might have to chase a CNAME chain internally, in which case
 	 * we'll have up to two replies and combine them to build a complete
 	 * answer.  These variables control this case. */
@@ -1088,11 +1104,11 @@
 	struct ub_packed_rrset_key* alias_rrset = NULL;
 	struct reply_info* partial_rep = NULL;
 	struct query_info* lookup_qinfo = &qinfo;
-	struct query_info qinfo_tmp; /* placeholdoer for lookup_qinfo */
+	struct query_info qinfo_tmp; /* placeholder for lookup_qinfo */
 	struct respip_client_info* cinfo = NULL, cinfo_tmp;
 	memset(&qinfo, 0, sizeof(qinfo));
 
-	if(error != NETEVENT_NOERROR) {
+	if(error != NETEVENT_NOERROR || !repinfo) {
 		/* some bad tcp query DNS formats give these error calls */
 		verbose(VERB_ALGO, "handle request called with err=%d", error);
 		return 0;
@@ -1171,11 +1187,11 @@
 
 	/* check if this query should be dropped based on source ip rate limiting */
 	if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
-			*worker->env.now)) {
+			*worker->env.now, c->buffer)) {
 		/* See if we are passed through with slip factor */
 		if(worker->env.cfg->ip_ratelimit_factor != 0 &&
 			ub_random_max(worker->env.rnd,
-						  worker->env.cfg->ip_ratelimit_factor) == 1) {
+						  worker->env.cfg->ip_ratelimit_factor) == 0) {
 
 			char addrbuf[128];
 			addr_to_str(&repinfo->addr, repinfo->addrlen,
@@ -1208,7 +1224,7 @@
 	if(worker->env.cfg->log_queries) {
 		char ip[128];
 		addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
-		log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
+		log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
 	}
 	if(qinfo.qtype == LDNS_RR_TYPE_AXFR || 
 		qinfo.qtype == LDNS_RR_TYPE_IXFR) {
@@ -1362,6 +1378,18 @@
 		goto send_reply;
 	}
 	if(worker->env.auth_zones &&
+		rpz_apply_qname_trigger(worker->env.auth_zones,
+		&worker->env, &qinfo, &edns, c->buffer, worker->scratchpad,
+		repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
+		regional_free_all(worker->scratchpad);
+		if(sldns_buffer_limit(c->buffer) == 0) {
+			comm_point_drop_reply(repinfo);
+			return 0;
+		}
+		server_stats_insrcode(&worker->stats, c->buffer);
+		goto send_reply;
+	}
+	if(worker->env.auth_zones &&
 		auth_zones_answer(worker->env.auth_zones, &worker->env,
 		&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
 		regional_free_all(worker->scratchpad);
@@ -1431,7 +1459,7 @@
 	/* If we may apply IP-based actions to the answer, build the client
 	 * information.  As this can be expensive, skip it if there is
 	 * absolutely no possibility of it. */
-	if(worker->daemon->use_response_ip &&
+	if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
 		(qinfo.qtype == LDNS_RR_TYPE_A ||
 		qinfo.qtype == LDNS_RR_TYPE_AAAA ||
 		qinfo.qtype == LDNS_RR_TYPE_ANY)) {
@@ -1452,12 +1480,14 @@
 	 * each pass.  We should still pass the original qinfo to
 	 * answer_from_cache(), however, since it's used to build the reply. */
 	if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) {
+		is_expired_answer = 0;
+		is_secure_answer = 0;
 		h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
 		if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
 			/* answer from cache - we have acquired a readlock on it */
 			if(answer_from_cache(worker, &qinfo,
-				cinfo, &need_drop, &alias_rrset, &partial_rep,
-				(struct reply_info*)e->data,
+				cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
+				&alias_rrset, &partial_rep, (struct reply_info*)e->data,
 				*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
 				sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
 				&edns)) {
@@ -1465,9 +1495,11 @@
 				 * Note that if there is more than one pass
 				 * its qname must be that used for cache
 				 * lookup. */
-				if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
-					&& *worker->env.now >=
-					((struct reply_info*)e->data)->prefetch_ttl) {
+				if((worker->env.cfg->prefetch && *worker->env.now >=
+							((struct reply_info*)e->data)->prefetch_ttl) ||
+						(worker->env.cfg->serve_expired &&
+						*worker->env.now >= ((struct reply_info*)e->data)->ttl)) {
+
 					time_t leeway = ((struct reply_info*)e->
 						data)->ttl - *worker->env.now;
 					if(((struct reply_info*)e->data)->ttl
@@ -1476,7 +1508,8 @@
 					lock_rw_unlock(&e->lock);
 					reply_and_prefetch(worker, lookup_qinfo,
 						sldns_buffer_read_u16_at(c->buffer, 2),
-						repinfo, leeway);
+						repinfo, leeway,
+						(partial_rep || need_drop));
 					if(!partial_rep) {
 						rc = 0;
 						regional_free_all(worker->scratchpad);
@@ -1551,6 +1584,13 @@
 		comm_point_drop_reply(repinfo);
 		return 0;
 	}
+	if(is_expired_answer) {
+		worker->stats.ans_expired++;
+	}
+	if(worker->stats.extended) {
+		if(is_secure_answer) worker->stats.ans_secure++;
+		server_stats_insrcode(&worker->stats, repinfo->c->buffer);
+	}
 #ifdef USE_DNSTAP
 	if(worker->dtenv.log_client_response_messages)
 		dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
@@ -1558,9 +1598,19 @@
 #endif
 	if(worker->env.cfg->log_replies)
 	{
-		struct timeval tv = {0, 0};
-		log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
-			tv, 1, c->buffer);
+		struct timeval tv;
+		memset(&tv, 0, sizeof(tv));
+		if(qinfo.local_alias && qinfo.local_alias->rrset &&
+			qinfo.local_alias->rrset->rk.dname) {
+			/* log original qname, before the local alias was
+			 * used to resolve that CNAME to something else */
+			qinfo.qname = qinfo.local_alias->rrset->rk.dname;
+			log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen,
+				tv, 1, c->buffer);
+		} else {
+			log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen,
+				tv, 1, c->buffer);
+		}
 	}
 #ifdef USE_DNSCRYPT
 	if(!dnsc_handle_uncurved_request(repinfo)) {
@@ -1667,11 +1717,7 @@
 		return NULL;
 	}
 	/* create random state here to avoid locking trouble in RAND_bytes */
-	seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
-		(((unsigned int)worker->thread_num)<<17);
-		/* shift thread_num so it does not match out pid bits */
-	if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) {
-		explicit_bzero(&seed, sizeof(seed));
+	if(!(worker->rndstate = ub_initstate(daemon->rand))) {
 		log_err("could not init random numbers.");
 		tube_delete(worker->cmd);
 		free(worker->ports);
@@ -1802,8 +1848,6 @@
 	alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
 	worker->env = *worker->daemon->env;
 	comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
-	if(worker->thread_num == 0)
-		log_set_time(worker->env.now);
 	worker->env.worker = worker;
 	worker->env.worker_base = worker->base;
 	worker->env.send_query = &worker_send_query;
@@ -1822,6 +1866,10 @@
 		return 0;
 	}
 	worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
+	/* Pass on daemon variables that we would need in the mesh area */
+	worker->env.mesh->use_response_ip = worker->daemon->use_response_ip;
+	worker->env.mesh->use_rpz = worker->daemon->use_rpz;
+
 	worker->env.detach_subs = &mesh_detach_subs;
 	worker->env.attach_sub = &mesh_attach_sub;
 	worker->env.add_sub = &mesh_add_sub;
@@ -1909,7 +1957,6 @@
 	comm_timer_delete(worker->env.probe_timer);
 	free(worker->ports);
 	if(worker->thread_num == 0) {
-		log_set_time(NULL);
 #ifdef UB_ON_WINDOWS
 		wsvc_desetup_worker(worker);
 #endif /* UB_ON_WINDOWS */
--- contrib/unbound/dns64/dns64.c.orig
+++ contrib/unbound/dns64/dns64.c
@@ -70,12 +70,9 @@
 #define MAX_PTR_QNAME_IPV4 30
 
 /**
- * Per-query module-specific state. This is usually a dynamically-allocated
- * structure, but in our case we only need to store one variable describing the
- * state the query is in. So we repurpose the minfo pointer by storing an
- * integer in there.
+ * State of DNS64 processing for a query.
  */
-enum dns64_qstate {
+enum dns64_state {
     DNS64_INTERNAL_QUERY,    /**< Internally-generated query, no DNS64
                                   processing. */
     DNS64_NEW_QUERY,         /**< Query for which we're the first module in
@@ -84,6 +81,19 @@
                                   for which this sub-query is finished. */
 };
 
+/**
+ * Per-query module-specific state.  For the DNS64 module.
+ */
+struct dns64_qstate {
+	/** State of the DNS64 module. */
+	enum dns64_state state;
+	/** If the dns64 module started with no_cache bool set in the qstate,
+	 * a message to tell it to not modify the cache contents, then this
+	 * is true.  The dns64 module is then free to modify that flag for
+	 * its own purposes.
+	 * Otherwise, it is false, the dns64 module was not told to no_cache */
+	int started_no_cache_store;
+};
 
 /******************************************************************************
  *                                                                            *
@@ -181,16 +191,19 @@
  *
  * \param ipv6   IPv6 address represented as a 128-bit array in big-endian
  *               order.
+ * \param ipv6_len length of the ipv6 byte array.
  * \param offset Index of the MSB of the IPv4 address embedded in the IPv6
  *               address.
  */
 static uint32_t
-extract_ipv4(const uint8_t ipv6[16], const int offset)
+extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset)
 {
-    uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
-                  | (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
-                  | (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
-                  | (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
+    uint32_t ipv4;
+    log_assert(ipv6_len == 16); (void)ipv6_len;
+    ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
+         | (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
+         | (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
+         | (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
     if (offset/8+4 < 16)
         ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8);
     return ipv4;
@@ -204,22 +217,26 @@
  * \param ipv4 IPv4 address represented as an unsigned 32-bit number.
  * \param ptr  The result will be written here. Must be large enough, be
  *             careful!
+ * \param nm_len length of the ptr buffer.
  *
  * \return The number of characters written.
  */
 static size_t
-ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
+ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len)
 {
     static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa";
     int i;
     char* c = ptr;
+    log_assert(nm_len == MAX_PTR_QNAME_IPV4);
 
     for (i = 0; i < 4; ++i) {
         *c = uitoa((unsigned int)(ipv4 % 256), c + 1);
         c += *c + 1;
+	log_assert(c < ptr+nm_len);
         ipv4 /= 256;
     }
 
+    log_assert(c + sizeof(IPV4_PTR_SUFFIX) <= ptr+nm_len);
     memmove(c, IPV4_PTR_SUFFIX, sizeof(IPV4_PTR_SUFFIX));
 
     return c + sizeof(IPV4_PTR_SUFFIX) - ptr;
@@ -231,13 +248,15 @@
  *
  * \param ptr  The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa")
  * \param ipv6 The result will be written here, in network byte order.
+ * \param ipv6_len length of the ipv6 byte array.
  *
  * \return 1 on success, 0 on failure.
  */
 static int
-ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
+ptr_to_ipv6(const char* ptr, uint8_t ipv6[], size_t ipv6_len)
 {
     int i;
+    log_assert(ipv6_len == 16); (void)ipv6_len;
 
     for (i = 0; i < 64; i++) {
         int x;
@@ -265,14 +284,20 @@
  * Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix.
  *
  * \param prefix_addr DNS64 prefix address.
+ * \param prefix_addr_len length of the prefix_addr buffer.
  * \param prefix_net  CIDR length of the DNS64 prefix. Must be between 0 and 96.
  * \param a           IPv4 address.
+ * \param a_len       length of the a buffer.
  * \param aaaa        IPv6 address. The result will be written here.
+ * \param aaaa_len    length of the aaaa buffer.
  */
 static void
-synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
-        const uint8_t a[4], uint8_t aaaa[16])
+synthesize_aaaa(const uint8_t prefix_addr[], size_t prefix_addr_len,
+	int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[],
+	size_t aaaa_len)
 {
+    log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16);
+    (void)prefix_addr_len; (void)a_len; (void)aaaa_len;
     memcpy(aaaa, prefix_addr, 16);
     aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8);
     aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8);
@@ -437,7 +462,8 @@
     /* Convert the PTR query string to an IPv6 address. */
     memset(&sin6, 0, sizeof(sin6));
     sin6.sin6_family = AF_INET6;
-    if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr))
+    if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr,
+	sizeof(sin6.sin6_addr.s6_addr)))
         return module_wait_module;  /* Let other module handle this. */
 
     /*
@@ -460,7 +486,8 @@
     if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4)))
         return module_error;
     qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr,
-                dns64_env->prefix_net), (char*)qinfo.qname);
+		sizeof(sin6.sin6_addr.s6_addr), dns64_env->prefix_net),
+		(char*)qinfo.qname, MAX_PTR_QNAME_IPV4);
 
     /* Create the new sub-query. */
     fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
@@ -470,7 +497,7 @@
     if (subq) {
         subq->curmod = id;
         subq->ext_state[id] = module_state_initial;
-        subq->minfo[id] = NULL;
+	subq->minfo[id] = NULL;
     }
 
     return module_wait_subquery;
@@ -540,7 +567,8 @@
 static enum module_ext_state
 handle_event_pass(struct module_qstate* qstate, int id)
 {
-	if ((uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
+	struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
+	if (iq && iq->state == DNS64_NEW_QUERY
             && qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
             && qstate->qinfo.qname_len == 74
             && !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa"))
@@ -548,12 +576,12 @@
         return handle_ipv6_ptr(qstate, id);
 
 	if (qstate->env->cfg->dns64_synthall &&
-	    (uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
+	    iq && iq->state == DNS64_NEW_QUERY
 	    && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
 		return generate_type_A_query(qstate, id);
 
 	if(dns64_always_synth_for_qname(qstate, id) &&
-	    (uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
+	    iq && iq->state == DNS64_NEW_QUERY
 	    && !(qstate->query_flags & BIT_CD)
 	    && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
 		verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
@@ -561,7 +589,7 @@
 	}
 
 	/* We are finished when our sub-query is finished. */
-	if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED)
+	if (iq && iq->state == DNS64_SUBQUERY_FINISHED)
 		return module_finished;
 
 	/* Otherwise, pass request to next module. */
@@ -582,6 +610,7 @@
 static enum module_ext_state
 handle_event_moddone(struct module_qstate* qstate, int id)
 {
+	struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
     /*
      * In many cases we have nothing special to do. From most to least common:
      *
@@ -593,7 +622,7 @@
      *        synthesize in (sec 5.1.2 of RFC6147).
      *   - A successful AAAA query with an answer.
      */
-	if((enum dns64_qstate)qstate->minfo[id] != DNS64_INTERNAL_QUERY
+	if((!iq || iq->state != DNS64_INTERNAL_QUERY)
             && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
 	    && !(qstate->query_flags & BIT_CD)
 	    && !(qstate->return_msg &&
@@ -604,7 +633,7 @@
 		 * So, this is a AAAA noerror/nodata answer */
 		return generate_type_A_query(qstate, id);
 
-	if((enum dns64_qstate)qstate->minfo[id] != DNS64_INTERNAL_QUERY
+	if((!iq || iq->state != DNS64_INTERNAL_QUERY)
 	    && qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
 	    && !(qstate->query_flags & BIT_CD)
 	    && dns64_always_synth_for_qname(qstate, id)) {
@@ -614,6 +643,13 @@
 		return generate_type_A_query(qstate, id);
 	}
 
+	/* Store the response in cache. */
+	if ( (!iq || !iq->started_no_cache_store) &&
+		qstate->return_msg && qstate->return_msg->rep &&
+		!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
+		0, 0, 0, NULL, qstate->query_flags))
+		log_err("out of memory");
+
 	/* do nothing */
 	return module_finished;
 }
@@ -634,6 +670,7 @@
 dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
 		struct outbound_entry* outbound)
 {
+	struct dns64_qstate* iq;
 	(void)outbound;
 	verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s",
 			id, strextstate(qstate->ext_state[id]),
@@ -643,7 +680,12 @@
 	switch(event) {
 		case module_event_new:
 			/* Tag this query as being new and fall through. */
-			qstate->minfo[id] = (void*)DNS64_NEW_QUERY;
+			iq = (struct dns64_qstate*)regional_alloc(
+				qstate->region, sizeof(*iq));
+			qstate->minfo[id] = iq;
+			iq->state = DNS64_NEW_QUERY;
+			iq->started_no_cache_store = qstate->no_cache_store;
+			qstate->no_cache_store = 1;
   			/* fallthrough */
 		case module_event_pass:
 			qstate->ext_state[id] = handle_event_pass(qstate, id);
@@ -655,6 +697,11 @@
 			qstate->ext_state[id] = module_finished;
 			break;
 	}
+	if(qstate->ext_state[id] == module_finished) {
+		iq = (struct dns64_qstate*)qstate->minfo[id];
+		if(iq && iq->state != DNS64_INTERNAL_QUERY)
+			qstate->no_cache_store = iq->started_no_cache_store;
+	}
 }
 
 static void
@@ -710,8 +757,10 @@
 		dd->rr_data[i][1] = 16;
 		synthesize_aaaa(
 				((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
+				sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr),
 				dns64_env->prefix_net, &fd->rr_data[i][2],
-				&dd->rr_data[i][2] );
+				fd->rr_len[i]-2, &dd->rr_data[i][2],
+				dd->rr_len[i]-2);
 		dd->rr_ttl[i] = fd->rr_ttl[i];
 	}
 
@@ -867,9 +916,10 @@
      * initial query's domain name.
      */
     answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep);
-    log_assert(answer);
-    answer->rk.dname = super->qinfo.qname;
-    answer->rk.dname_len = super->qinfo.qname_len;
+    if(answer) {
+	    answer->rk.dname = super->qinfo.qname;
+	    answer->rk.dname_len = super->qinfo.qname_len;
+    }
 }
 
 /**
@@ -885,6 +935,7 @@
 dns64_inform_super(struct module_qstate* qstate, int id,
 		struct module_qstate* super)
 {
+	struct dns64_qstate* super_dq = (struct dns64_qstate*)super->minfo[id];
 	log_query_info(VERB_ALGO, "dns64: inform_super, sub is",
 		       &qstate->qinfo);
 	log_query_info(VERB_ALGO, "super is", &super->qinfo);
@@ -893,15 +944,27 @@
 	 * Signal that the sub-query is finished, no matter whether we are
 	 * successful or not. This lets the state machine terminate.
 	 */
-	super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED;
+	if(!super_dq) {
+		super_dq = (struct dns64_qstate*)regional_alloc(super->region,
+			sizeof(*super_dq));
+		if(!super_dq) {
+			log_err("out of memory");
+			super->return_rcode = LDNS_RCODE_SERVFAIL;
+			super->return_msg = NULL;
+			return;
+		}
+		super->minfo[id] = super_dq;
+		memset(super_dq, 0, sizeof(*super_dq));
+		super_dq->started_no_cache_store = super->no_cache_store;
+	}
+	super_dq->state = DNS64_SUBQUERY_FINISHED;
 
 	/* If there is no successful answer, we're done. */
 	if (qstate->return_rcode != LDNS_RCODE_NOERROR
 	    || !qstate->return_msg
-	    || !qstate->return_msg->rep
-	    || !reply_find_answer_rrset(&qstate->qinfo,
-					qstate->return_msg->rep))
+	    || !qstate->return_msg->rep) {
 		return;
+	}
 
 	/* Use return code from A query in response to client. */
 	if (super->return_rcode != LDNS_RCODE_NOERROR)
@@ -916,7 +979,7 @@
 	}
 
 	/* Store the generated response in cache. */
-	if (!super->no_cache_store &&
+	if ( (!super_dq || !super_dq->started_no_cache_store) &&
 		!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
 		0, 0, 0, NULL, super->query_flags))
 		log_err("out of memory");
--- contrib/unbound/dnscrypt/dnscrypt.c.orig
+++ contrib/unbound/dnscrypt/dnscrypt.c
@@ -316,15 +316,15 @@
 #else
             return -1;
 #endif
-    } else {
-        if (crypto_box_beforenm(nmkey,
-                                query_header->publickey,
-                                cert->keypair->crypt_secretkey) != 0) {
-            return -1;
-        }
-    }
-    // Cache the shared secret we just computed.
-    dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
+	} else {
+	    if (crypto_box_beforenm(nmkey,
+				    query_header->publickey,
+				    cert->keypair->crypt_secretkey) != 0) {
+		return -1;
+	    }
+	}
+        // Cache the shared secret we just computed.
+        dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
                                     key,
                                     hash,
                                     nmkey);
@@ -442,20 +442,7 @@
 static void
 add_server_nonce(uint8_t *nonce)
 {
-    uint64_t ts;
-    uint64_t tsn;
-    uint32_t suffix;
-    ts = dnscrypt_hrtime();
-    // TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
-    // unclear if we really need it, so skipping it for now.
-    tsn = (ts << 10) | (randombytes_random() & 0x3ff);
-#if (BYTE_ORDER == LITTLE_ENDIAN)
-    tsn =
-        (((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
-#endif
-    memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
-    suffix = randombytes_random();
-    memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
+    randombytes_buf(nonce + crypto_box_HALF_NONCEBYTES, 8/*tsn*/+4/*suffix*/);
 }
 
 /**
@@ -732,6 +719,11 @@
             );
             continue;
         }
+	if((unsigned)strlen(dnscenv->provider_name) >= (unsigned)0xffff0000) {
+		/* guard against integer overflow in rrlen calculation */
+		verbose(VERB_OPS, "cert #%" PRIu32 " is too long", serial);
+		continue;
+	}
         rrlen = strlen(dnscenv->provider_name) +
                          strlen(ttl_class_type) +
                          4 * sizeof(struct SignedCert) + // worst case scenario
@@ -746,9 +738,9 @@
         for(j=0; j<sizeof(struct SignedCert); j++) {
 			int c = (int)*((const uint8_t *) cert + j);
             if (isprint(c) && c != '"' && c != '\\') {
-                snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
+                snprintf(rr + strlen(rr), rrlen - strlen(rr), "%c", c);
             } else {
-                snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
+                snprintf(rr + strlen(rr), rrlen - strlen(rr), "\\%03d", c);
             }
         }
         verbose(VERB_OPS,
@@ -757,7 +749,7 @@
 			" to local-data to config: %s",
 			serial, rr
 		);
-        snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
+        snprintf(rr + strlen(rr), rrlen - strlen(rr), "\"");
         cfg_strlist_insert(&cfg->local_data, strdup(rr));
         free(rr);
     }
@@ -772,12 +764,13 @@
         const char *name;
     };
 
+    const int num_versions = 2;
     struct es_version es_versions[] = {
         {{0x00, 0x01}, "X25519-XSalsa20Poly1305"},
         {{0x00, 0x02}, "X25519-XChacha20Poly1305"},
     };
     int i;
-    for(i=0; i < (int)sizeof(es_versions); i++){
+    for(i=0; i < num_versions; i++){
         if(es_versions[i].es_version[0] == version[0] &&
            es_versions[i].es_version[1] == version[1]){
             return es_versions[i].name;
@@ -876,7 +869,7 @@
 	fatal_exit(
 		"dnscrypt: libsodium could not be initialized, this typically"
 		" happens when no good source of entropy is found. If you run"
-		" unbound in a chroot, make sure /dev/random is available. See"
+		" unbound in a chroot, make sure /dev/urandom is available. See"
 		" https://www.unbound.net/documentation/unbound.conf.html");
 }
 
--- contrib/unbound/dnstap/dnstap.c.orig
+++ contrib/unbound/dnstap/dnstap.c
@@ -39,6 +39,10 @@
 #include "config.h"
 #include <string.h>
 #include <sys/time.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <errno.h>
 #include "sldns/sbuffer.h"
 #include "util/config_file.h"
 #include "util/net_help.h"
@@ -118,6 +122,18 @@
 	}
 }
 
+/* check that the socket file can be opened and exists, print error if not */
+static void
+check_socket_file(const char* socket_path)
+{
+	struct stat statbuf;
+	memset(&statbuf, 0, sizeof(statbuf));
+	if(stat(socket_path, &statbuf) < 0) {
+		log_warn("could not open dnstap-socket-path: %s, %s",
+			socket_path, strerror(errno));
+	}
+}
+
 struct dt_env *
 dt_create(const char *socket_path, unsigned num_workers)
 {
@@ -134,6 +150,7 @@
 		socket_path);
 	log_assert(socket_path != NULL);
 	log_assert(num_workers > 0);
+	check_socket_file(socket_path);
 
 	env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
 	if (!env)
--- contrib/unbound/doc/Changelog.orig
+++ contrib/unbound/doc/Changelog
@@ -1,8 +1,1042 @@
+20 February 2020: Wouter
+	- Updated contrib/unbound_smf23.tar.gz with Solaris SMF service for
+	  Unbound from Yuri Voinov.
+
+17 February 2020: Ralph
+	- Add respip to supported module-config options in unbound-checkconf.
+
+17 February 2020: George
+	- Remove unused variable.
+
+17 February 2020: Wouter
+	- contrib/drop2rpz: perl script that converts the Spamhaus DROP-List
+	  in RPZ-Format, contributed by Andreas Schulze.
+
+14 February 2020: Wouter
+	- Fix spelling in unbound.conf.5.in.
+	- Stop unbound-checkconf from insisting that auth-zone and rpz
+	  zonefiles have to exist.  They can not exist, and download later.
+
+13 February 2020: Wouter
+	- tag for 1.10.0rc1 release.
+
+12 February 2020: Wouter
+	- Fix with libnettle make test with dsa disabled.
+	- Fix contrib/fastrpz.patch to apply cleanly.  Fix for serve-stale
+	  fixes, but it does not compile, conflicts with new rpz code.
+	- Fix to clean memory leak of respip_addr.lock when ip_tree deleted.
+	- Fix compile warning when threads disabled.
+	- updated version number to 1.10.0.
+
+10 February 2020: George
+	- Document 'ub_result.was_ratelimited' in libunbound.
+	- Fix use after free on log-identity after a reload; Fixes #163.
+
+6 February 2020: George
+	- Fix num_reply_states and num_detached_states counting with
+	  serve_expired_callback.
+	- Cleaner code in mesh_serve_expired_lookup.
+	- Document in unbound.conf manpage that configuration clauses can be
+	  repeated in the configuration file.
+
+6 February 2020: Wouter
+	- Fix num_reply_addr counting in mesh and tcp drop due to size
+	  after serve_stale commit.
+	- Fix to create and destroy rpz_lock in auth_zones structure.
+	- Fix to lock zone before adding rpz qname trigger.
+	- Fix to lock and release once in mesh_serve_expired_lookup.
+	- Fix to put braces around empty if body when threading is disabled.
+
+5 February 2020: George
+	- Added serve-stale functionality as described in
+	  draft-ietf-dnsop-serve-stale-10. `serve-expired-*` options can be used
+	  to configure the behavior.
+	- Updated cachedb to honor `serve-expired-ttl`; Fixes #107.
+	- Renamed statistic `num.zero_ttl` to `num.expired` as expired replies
+	  come with a configurable TTL value (`serve-expired-reply-ttl`).
+	- Fixed stats when replying with cached, cname-aliased records.
+	- Added missing default values for redis cachedb backend.
+
+3 February 2020: Ralph
+	- Add assertion to please static analyzer
+
+31 January 2020: Wouter
+	- Fix fclose on error in TLS session ticket code.
+
+30 January 2020: Ralph
+	- Fix memory leak in error condition remote.c
+	- Fix double free in error condition view.c
+	- Fix memory leak in do_auth_zone_transfer on success
+	- Merge RPZ support into master. Only QNAME and Response IP triggers are
+	  supported.
+	- Stop working on socket when socket() call returns an error.
+	- Check malloc return values in TLS session ticket code
+
+30 January 2020: Wouter
+	- Fix subnet tests for disabled DSA algorithm by default.
+	- Update contrib/fastrpz.patch for clean diff with current code.
+	- Merge PR#151: Fixes for systemd units, by Maryse47, Edmonds
+	  and Frzk.  Updates the unbound.service systemd file and adds
+	  a portable systemd service file.
+	- updated .gitignore for added contrib file.
+	- Add build rule for ipset to Makefile
+	- Add getentropy_freebsd.o to Makefile dependencies.
+
+29 January 2020: Ralph
+	- Merge PR#156 from Alexander Berkes; Added unbound-control
+	  view_local_datas_remove command.
+
+29 January 2020: Wouter
+	- Fix #157: undefined reference to `htobe64'.
+
+28 January 2020: Ralph
+	- Merge PR#147; change rfc reference for reserved top level dns names.
+
+28 January 2020: Wouter
+	- iana portlist updated.
+	- Fix to silence the tls handshake errors for broken pipe and reset
+	  by peer, unless verbosity is set to 2 or higher.
+
+27 January 2020: Ralph
+	- Merge PR#154; Allow use of libbsd functions with configure option
+	  --with-libbsd. By Robert Edmonds and Steven Chamberlain.
+	- Merge PR#148; Add some TLS stats to unbound_munin_. By Fredrik Pettai.
+
+27 January 2020: Wouter
+	- Merge PR#155 from Robert Edmonds: contrib/libunbound.pc.in: Fixes
+	  to Libs/Requires for crypto library dependencies.
+	- Fix #153: Disable validation for DSA algorithms.  RFC 8624
+	  compliance.
+
+23 January 2020: Wouter
+	- Merge PR#150 from Frzk: Systemd unit without chroot.  It add
+	  contrib/unbound_nochroot.service.in, a systemd file for use with
+	  chroot: "", see comments in the file, it uses systemd protections
+	  instead.
+
+14 January 2020: Wouter
+	- Removed the dnscrypt_queries and dnscrypt_queries_chacha tests,
+	  because dnscrypt-proxy (2.0.36) does not support the test setup
+	  any more, and also the config file format does not seem to have
+	  the appropriate keys to recreate that setup.
+	- Fix crash after reload where a stats lookup could reference old key
+	  cache and neg cache structures.
+	- Fix for memory leak when edns subnet config options are read when
+	  compiled without edns subnet support.
+	- Fix auth zone support for NSEC3 records without salt.
+
+10 January 2020: Wouter
+	- Fix the relationship between serve-expired and prefetch options,
+	  patch from Saksham Manchanda from Secure64.
+	- Fix unreachable code in ssl set options code.
+
+8 January 2020: Ralph
+	- Fix #138: stop binding pidfile inside chroot dir in systemd service
+	  file.
+
+8 January 2020: Wouter
+	- Fix 'make test' to work for --disable-sha1 configure option.
+	- Fix out-of-bounds null-byte write in sldns_bget_token_par while
+	  parsing type WKS, reported by Luis Merino from X41 D-Sec.
+	- Updated sldns_bget_token_par fix for also space for the zero
+	  delimiter after the character.  And update for more spare space.
+
+6 January 2020: George
+	- Downgrade compat/getentropy_solaris.c to version 1.4 from OpenBSD.
+	  The dl_iterate_phdr() function introduced in newer versions raises
+	  compilation errors on solaris 10.
+	- Changes to compat/getentropy_solaris.c for,
+	  ifdef stdint.h inclusion for older systems.
+	  ifdef sha2.h inclusion for older systems.
+
+6 January 2020: Wouter
+	- Merge #135 from Florian Obser: Use passed in neg and key cache
+	  if non-NULL.
+	- Fix #140: Document slave not downloading new zonefile upon update.
+
+16 December 2019: George
+	- Update mailing list URL.
+
+12 December 2019: Ralph
+	- Master is 1.9.7 in development.
+	- Fix typo to let serve-expired-ttl work with ub_ctx_set_option(), by
+	  Florian Obser
+
+10 December 2019: Wouter
+	- Fix to make auth zone IXFR to fallback to AXFR if a single
+	  response RR is received over TCP with the SOA in it.
+
+6 December 2019: Wouter
+	- Fix ipsecmod compile.
+	- Fix Makefile.in for ipset module compile, from Adi Prasaja.
+	- release-1.9.6 tag, which became the 1.9.6 release
+
+5 December 2019: Wouter
+	- unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1
+	  replacements for unbound-fuzzme.c that gets created after applying
+	  the contrib/unbound-fuzzme.patch.  They are contributed by
+	  Eric Sesterhenn from X41 D-Sec.
+	- tag for 1.9.6rc1.
+
+4 December 2019: Wouter
+	- Fix lock type for memory purify log lock deletion.
+	- Fix testbound for alloccheck runs, memory purify and lock checks.
+	- update contrib/fastrpz.patch to apply more cleanly.
+	- Fix Make Test Fails when Configured With --enable-alloc-nonregional,
+	  reported by X41 D-Sec.
+
+3 December 2019: Wouter
+	- Merge pull request #124 from rmetrich: Changed log lock
+	  from 'quick' to 'basic' because this is an I/O lock.
+	- Fix text around serial arithmatic used for RRSIG times to refer
+	  to correct RFC number.
+	- Fix Assert Causing DoS in synth_cname(),
+	  reported by X41 D-Sec.
+	- Fix similar code in auth_zone synth cname to add the extra checks.
+	- Fix Assert Causing DoS in dname_pkt_copy(),
+	  reported by X41 D-Sec.
+	- Fix OOB Read in sldns_wire2str_dname_scan(),
+	  reported by X41 D-Sec.
+	- Fix Out of Bounds Write in sldns_str2wire_str_buf(),
+	  reported by X41 D-Sec.
+	- Fix Out of Bounds Write in sldns_b64_pton(),
+	  fixed by check in sldns_str2wire_int16_data_buf(),
+	  reported by X41 D-Sec.
+	- Fix Insufficient Handling of Compressed Names in dname_pkt_copy(),
+	  reported by X41 D-Sec.
+	- Fix Out of Bound Write Compressed Names in rdata_copy(),
+	  reported by X41 D-Sec.
+	- Fix Hang in sldns_wire2str_pkt_scan(),
+	  reported by X41 D-Sec.
+	  This further lowers the max to 256.
+	- Fix snprintf() supports the n-specifier,
+	  reported by X41 D-Sec.
+	- Fix Bad Indentation, in dnscrypt.c,
+	  reported by X41 D-Sec.
+	- Fix Client NONCE Generation used for Server NONCE,
+	  reported by X41 D-Sec.
+	- Fix compile error in dnscrypt.
+	- Fix _vfixed not Used, removed from sbuffer code,
+	  reported by X41 D-Sec.
+	- Fix Hardcoded Constant, reported by X41 D-Sec.
+	- make depend
+
+2 December 2019: Wouter
+	- Merge pull request #122 from he32: In tcp_callback_writer(),
+	  don't disable time-out when changing to read.
+
+22 November 2019: George
+	- Fix compiler warnings.
+
+22 November 2019: Wouter
+	- Fix dname loop maximum, reported by Eric Sesterhenn from X41 D-Sec.
+	- Add make distclean that removes everything configure produced,
+	  and make maintainer-clean that removes bison and flex output.
+
+20 November 2019: Wouter
+	- Fix Out of Bounds Read in rrinternal_get_owner(),
+	  reported by X41 D-Sec.
+	- Fix Race Condition in autr_tp_create(),
+	  reported by X41 D-Sec.
+	- Fix Shared Memory World Writeable,
+	  reported by X41 D-Sec.
+	- Adjust unbound-control to make stats_shm a read only operation.
+	- Fix Weak Entropy Used For Nettle,
+	  reported by X41 D-Sec.
+	- Fix Randomness Error not Handled Properly,
+	  reported by X41 D-Sec.
+	- Fix Out-of-Bounds Read in dname_valid(),
+	  reported by X41 D-Sec.
+	- Fix Config Injection in create_unbound_ad_servers.sh,
+	  reported by X41 D-Sec.
+	- Fix Local Memory Leak in cachedb_init(),
+	  reported by X41 D-Sec.
+	- Fix Integer Underflow in Regional Allocator,
+	  reported by X41 D-Sec.
+	- Upgrade compat/getentropy_linux.c to version 1.46 from OpenBSD.
+	- Synchronize compat/getentropy_win.c with version 1.5 from
+	  OpenBSD, no changes but makes the file, comments, identical.
+	- Upgrade compat/getentropy_solaris.c to version 1.13 from OpenBSD.
+	- Upgrade compat/getentropy_osx.c to version 1.12 from OpenBSD.
+	- Changes to compat/getentropy files for,
+	  no link to openssl if using nettle, and hence config.h for
+	  HAVE_NETTLE variable.
+	  compat definition of MAP_ANON, for older systems.
+	  ifdef stdint.h inclusion for older systems.
+	  ifdef sha2.h inclusion for older systems.
+	- Fixed Compat Code Diverging from Upstream, reported by X41 D-Sec.
+	- Fix compile with --enable-alloc-checks, reported by X41 D-Sec.
+	- Fix Terminating Quotes not Written, reported by X41 D-Sec.
+	- Fix Useless memset() in validator, reported by X41 D-Sec.
+	- Fix Unrequired Checks, reported by X41 D-Sec.
+	- Fix Enum Name not Used, reported by X41 D-Sec.
+	- Fix NULL Pointer Dereference via Control Port,
+	  reported by X41 D-Sec.
+	- Fix Bad Randomness in Seed, reported by X41 D-Sec.
+	- Fix python examples/calc.py for eval, reported by X41 D-Sec.
+	- Fix comments for doxygen in dns64.
+
+19 November 2019: Wouter
+	- Fix CVE-2019-18934, shell execution in ipsecmod.
+	- 1.9.5 is 1.9.4 with bugfix, trunk is 1.9.6 in development.
+	- Fix authzone printout buffer length check.
+	- Fixes to please lint checks.
+	- Fix Integer Overflow in Regional Allocator,
+	  reported by X41 D-Sec.
+	- Fix Unchecked NULL Pointer in dns64_inform_super()
+	  and ipsecmod_new(), reported by X41 D-Sec.
+	- Fix Out-of-bounds Read in rr_comment_dnskey(),
+	  reported by X41 D-Sec.
+	- Fix Integer Overflows in Size Calculations,
+	  reported by X41 D-Sec.
+	- Fix Integer Overflow to Buffer Overflow in
+	  sldns_str2wire_dname_buf_origin(), reported by X41 D-Sec.
+	- Fix Out of Bounds Read in sldns_str2wire_dname(),
+	  reported by X41 D-Sec.
+	- Fix Out of Bounds Write in sldns_bget_token_par(),
+	  reported by X41 D-Sec.
+
+18 November 2019: Wouter
+	- In unbound-host use separate variable for get_option to please
+	  code checkers.
+	- update to bison output of 3.4.1 in code repository.
+	- Provide a prototype for compat malloc to remove compile warning.
+	- Portable grep usage for reuseport configure test.
+	- Check return type of HMAC_Init_ex for openssl 0.9.8.
+	- gitignore .source tempfile used for compatible make.
+
+13 November 2019: Wouter
+	- iana portlist updated.
+	- contrib/fastrpz.patch updated to apply for current code.
+	- fixes for splint cleanliness, long vs int in SSL set_mode.
+
+11 November 2019: Wouter
+	- Fix #109: check number of arguments for stdin-pipes in
+	  unbound-control and fail if too many arguments.
+	- Merge #102 from jrtc27: Add getentropy emulation for FreeBSD.
+
+24 October 2019: Wouter
+	- Fix #99: Memory leak in ub_ctx (event_base will never be freed).
+
+23 October 2019: George
+	- Add new configure option `--enable-fully-static` to enable full static
+	  build if requested; in relation to #91.
+
+23 October 2019: Wouter
+	- Merge #97: manpage: Add missing word on unbound.conf,
+	  from Erethon.
+
+22 October 2019: Wouter
+	- drop-tld.diff: adds option drop-tld: yesno that drops 2 label
+	  queries, to stop random floods.  Apply with
+	  patch -p1 < contrib/drop-tld.diff and compile.
+	  From Saksham Manchanda (Secure64).  Please note that we think this
+	  will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
+	  lookups for downstream clients.
+
+7 October 2019: Wouter
+	- Add doxygen comments to unbound-anchor source address code, in #86.
+
+3 October 2019: Wouter
+	- Merge #90 from vcunat: fix build with nettle-3.5.
+	- Merge 1.9.4 release with fix for vulnerability CVE-2019-16866.
+	- Continue with development of 1.9.5.
+	- Merge #86 from psquarejho: Added -b source address option to
+	  smallapp/unbound-anchor.c, from Lukas Wunner.
+
+26 September 2019: Wouter
+	- Merge #87 from hardfalcon: Fix contrib/unbound.service.in,
+	  Drop CAP_KILL, use + prefix for ExecReload= instead.
+
+25 September 2019: Wouter
+	- The unbound.conf includes are sorted ascending, for include
+	  statements with a '*' from glob.
+
+23 September 2019: Wouter
+	- Merge #85 for #84 from sam-lunt: Add kill capability to systemd
+	  service file to fix that systemctl reload fails.
+
+20 September 2019: Wouter
+	- Merge #82 from hardfalcon: Downgrade CAP_NET_ADMIN to CAP_NET_RAW
+	  in unbound.service.
+	- Merge #81 from Maryse47: Consistently use /dev/urandom instead
+	  of /dev/random in scripts and docs.
+	- Merge #83 from Maryse47: contrib/unbound.service.in: do not fork
+	  into the background.
+
+19 September 2019: Wouter
+	- Fix #78: Memory leak in outside_network.c.
+	- Merge pull request #76 from Maryse47: Improvements and fixes for
+	  systemd unbound.service.
+	- oss-fuzz badge on README.md.
+	- Fix fix for #78 to also free service callback struct.
+	- Fix for oss-fuzz build warning.
+	- Fix wrong response ttl for prepended short CNAME ttls, this would
+	  create a wrong zero_ttl response count with serve-expired enabled.
+	- Merge #80 from stasic: Improve wording in man page.
+
+11 September 2019: Wouter
+	- Use explicit bzero for wiping clear buffer of hash in cachedb,
+	  reported by Eric Sesterhenn from X41 D-Sec.
+
+9 September 2019: Wouter
+	- Fix #72: configure --with-syslog-facility=LOCAL0-7 with default
+	  LOG_DAEMON (as before) can set the syslog facility that the server
+	  uses to log messages.
+
+4 September 2019: Wouter
+	- Fix #71: fix openssl error squelch commit compilation error.
+
+3 September 2019: Wouter
+	- squelch DNS over TLS errors 'ssl handshake failed crypto error'
+	  on low verbosity, they show on verbosity 3 (query details), because
+	  there is a high volume and the operator cannot do anything for the
+	  remote failure.  Specifically filters the high volume errors.
+
+2 September 2019: Wouter
+	- ipset module #28: log that an address is added, when verbosity high.
+	- ipset: refactor long routine into three smaller ones.
+	- updated Makefile dependencies.
+
+23 August 2019: Wouter
+	- Fix contrib/fastrpz.patch asprintf return value checks.
+
+22 August 2019: Wouter
+	- Fix that pkg-config is setup before --enable-systemd needs it.
+	- 1.9.3rc2 release candidate tag.  And this became the 1.9.3 release.
+	  Master is 1.9.4 in development.
+
+21 August 2019: Wouter
+	- Fix log_dns_msg to log irrespective of minimal responses config.
+
+19 August 2019: Ralph
+	- Document limitation of pidfile removal outside of chroot directory.
+
+16 August 2019: Wouter
+	- Fix unittest valgrind false positive uninitialised value report,
+	  where if gcc 9.1.1 uses -O2 (but not -O1) then valgrind 3.15.0
+	  issues an uninitialised value for the token buffer at the str2wire.c
+	  rrinternal_get_owner() strcmp with the '@' value.  Rewritten to use
+	  straight character comparisons removes the false positive.  Also
+	  valgrinds --expensive-definedness-checks=yes can stop this false
+	  positive.
+	- Please doxygen's parser for "@" occurrence in doxygen comment.
+	- Fixup contrib/fastrpz.patch
+	- Remove warning about unknown cast-function-type warning pragma.
+
+15 August 2019: Wouter
+	- iana portlist updated.
+	- Fix autotrust temp file uniqueness windows compile.
+	- avoid warning about upcast on 32bit systems for autotrust.
+	- escape commandline contents for -V.
+	- Fix character buffer size in ub_ctx_hosts.
+	- 1.9.3rc1 release candidate tag.
+	- Option -V prints if TCP fastopen is available.
+
+14 August 2019: George
+	- Fix #59, when compiled with systemd support check that we can properly
+	  communicate with systemd through the `NOTIFY_SOCKET`.
+
+14 August 2019: Wouter
+	- Generate configlexer with newer flex.
+	- Fix warning for unused variable for compilation without systemd.
+
+12 August 2019: George
+	- Introduce `-V` option to print the version number and build options.
+	  Previously reported build options like linked libs and linked modules
+	  are now moved from `-h` to `-V` as well for consistency.
+	- PACKAGE_BUGREPORT now also includes link to GitHub issues.
+
+1 August 2019: Wouter
+	- For #52 #53, second context does not close logfile override.
+	- Fix #52 #53, fix for example fail program.
+	- Fix to return after failed auth zone http chunk write.
+	- Fix to remove unused test for task_probe existance.
+	- Fix to timeval_add for remaining second in microseconds.
+	- Check repinfo in worker_handle_request, if null, drop it.
+
+29 July 2019: Wouter
+	- Add verbose log message when auth zone file is written, at level 4.
+	- Add hex print of trust anchor pointer to trust anchor file temp
+	  name to make it unique, for libunbound created multiple contexts.
+
+23 July 2019: Wouter
+	- Fix question section mismatch in local zone redirect.
+
+19 July 2019: Wouter
+	- Fix #49: Set no renegotiation on the SSL context to stop client
+	  session renegotiation.
+
+12 July 2019: Wouter
+	- Fix #48: Unbound returns additional records on NODATA response,
+	  if minimal-responses is enabled, also the additional for negative
+	  responses is removed.
+
+9 July 2019: Ralph
+	- Fix in respip addrtree selection. Absence of addr_tree_init_parents()
+	  call made it impossible to go up the tree when the matching netmask is
+	  too specific.
+
+5 July 2019: Ralph
+	- Fix for possible assertion failure when answering respip CNAME from
+	  cache.
+
+25 June 2019: Wouter
+	- For #45, check that 127.0.0.1 and ::1 are not used in unbound.conf
+	  when do-not-query-localhost is turned on, or at default on,
+	  unbound-checkconf prints a warning if it is found in forward-addr or
+	  stub-addr statements.
+
+24 June 2019: Wouter
+	- Fix memleak in unit test, reported from the clang 8.0 static analyzer.
+
+18 June 2019: Wouter
+	- PR #28: IPSet module, by Kevin Chou.  Created a module to support
+	  the ipset that could add the domain's ip to a list easily.
+	  Needs libmnl, and --enable-ipset and config it, doc/README.ipset.md.
+	- Fix to omit RRSIGs from addition to the ipset.
+	- Fix to make unbound-control with ipset, remove unused variable,
+	  use unsigned type because of comparison, and assign null instead
+	  of compare with it.  Remade lex and yacc output.
+	- make depend
+	- Added documentation to the ipset files (for doxygen output).
+	- Merge PR #6: Python module: support multiple instances
+	- Merge PR #5: Python module: define constant MODULE_RESTART_NEXT
+	- Merge PR #4: Python module: assign something useful to the
+	  per-query data store 'qdata'
+	- Fix python dict reference and double free in config.
+
+17 June 2019: Wouter
+	- Master contains version 1.9.3 in development.
+	- Fix #39: In libunbound, leftover logfile is close()d unpredictably.
+	- Fix for #24: Fix abort due to scan of auth zone masters using old
+	  address from previous scan.
+
+12 June 2019: Wouter
+	- Fix another spoolbuf storage code point, in prefetch.
+	- 1.9.2rc3 release candidate tag.  Which became the 1.9.2 release
+	  on 17 June 2019.
+
+11 June 2019: Wouter
+	- Fix that fixes the Fix that spoolbuf is not used to store tcp
+	  pipelined response between mesh send and callback end, this fixes
+	  error cases that did not use the correct spoolbuf.
+	- 1.9.2rc2 release candidate tag.
+
+6 June 2019: Wouter
+	- 1.9.2rc1 release candidate tag.
+
+4 June 2019: Wouter
+	- iana portlist updated.
+
+29 May 2019: Wouter
+	- Fix to guard _OPENBSD_SOURCE from redefinition.
+
+28 May 2019: Wouter
+	- Fix to define _OPENBSD_SOURCE to get reallocarray on NetBSD.
+	- gitignore config.h.in~.
+
+27 May 2019: Wouter
+	- Fix double file close in tcp pipelined response code.
+
+24 May 2019: Wouter
+	- Fix that spoolbuf is not used to store tcp pipelined response
+	  between mesh send and callback end.
+
+20 May 2019: Wouter
+	- Note that so-reuseport at extreme load is better turned off,
+	  otherwise queries are not distributed evenly, on Linux 4.4.x.
+
+16 May 2019: Wouter
+	- Fix #31: swig 4.0 and python module.
+
+13 May 2019: Wouter
+	- Squelch log messages from tcp send about connection reset by peer.
+	  They can be enabled with verbosity at higher values for diagnosing
+	  network connectivity issues.
+	- Attempt to fix malformed tcp response.
+
+9 May 2019: Wouter
+	- Revert fix for oss-fuzz, error is in that build script that
+	  unconditionally includes .o files detected by configure, also
+	  when the machine architecture uses different LIBOBJS files.
+
+8 May 2019: Wouter
+	- Attempt to fix build failure in oss-fuzz because of reallocarray.
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14648.
+	  Does not omit compile flags from commandline.
+
+7 May 2019: Wouter
+	- Fix edns-subnet locks, in error cases the lock was not unlocked.
+	- Fix doxygen output error on readme markdown vignettes.
+
+6 May 2019: Wouter
+	- Fix #29: Solaris 11.3 and missing symbols be64toh, htobe64.
+	- Fix #30: AddressSanitizer finding in lookup3.c.  This sets the
+	  hash function to use a slower but better auditable code that does
+	  not read beyond array boundaries.  This makes code better security
+	  checkable, and is better for security.  It is fixed to be slower,
+	  but not read outside of the array.
+
+2 May 2019: Wouter
+	- contrib/fastrpz.patch updated for code changes, and with git diff.
+	- Fix .gitignore, add pythonmod and dnstap generated files.
+	  And unit test generated files, and generated doc files.
+
+1 May 2019: Wouter
+	- Update makedist for git.
+	- Nicer travis output for clang analysis.
+	- PR #16: XoT support, AXFR over TLS, turn it on with
+	  master: <ip>#<authname> in unbound.conf.  This uses TLS to
+	  download the AXFR (or IXFR).
+
+25 April 2019: Wouter
+	- Fix wrong query name in local zone redirect answers with a CNAME,
+	  the copy of the local alias is in unpacked form.
+
+18 April 2019: Ralph
+	- Scrub RRs from answer section when reusing NXDOMAIN message for
+	  subdomain answers.
+	- For harden-below-nxdomain: do not consider a name to be non-exitent
+	  when message contains a CNAME record.
+
+18 April 2019: Wouter
+	- travis build file.
+
+16 April 2019: Wouter
+	- Better braces in if statement in TCP fastopen code.
+	- iana portlist updated.
+
+15 April 2019: Wouter
+	- Fix tls write event for read state change to re-call SSL_write and
+	  not resume the TLS handshake.
+
+11 April 2019: George
+	- Update python documentation for init_standard().
+	- Typos.
+
+11 April 2019: Wouter
+	- Fix that auth zone uses correct network type for sockets for
+	  SOA serial probes.  This fixes that probes fail because earlier
+	  probe addresses are unreachable.
+	- Fix that auth zone fails over to next master for timeout in tcp.
+	- Squelch SSL read and write connection reset by peer and broken pipe 
+	  messages.  Verbosity 2 and higher enables them.
+
+8 April 2019: Wouter
+	- Fix to use event_assign with libevent for thread-safety.
+	- verbose information about auth zone lookup process, also lookup
+	  start, timeout and fail.
+	- Fix #17: Add python module example from Jan Janak, that is a
+	  plugin for the Unbound DNS resolver to resolve DNS records in
+	  multicast DNS [RFC 6762] via Avahi.  The plugin communicates
+	  with Avahi via DBus. The comment section at the beginning of
+	  the file contains detailed documentation.
+	- Fix to wipe ssl ticket keys from memory with explicit_bzero,
+	  if available.
+
+5 April 2019: Wouter
+	- Fix to reinit event structure for accepted TCP (and TLS) sockets.
+
+4 April 2019: Wouter
+	- Fix spelling error in log output for event method.
+
+3 April 2019: Wouter
+	- Move goto label in answer_from_cache to the end of the function
+	  where it is more visible.
+	- Fix auth-zone NSEC3 response for wildcard nodata answers,
+	  include the closest encloser in the answer.
+
+2 April 2019: Wouter
+	- Fix auth-zone NSEC3 response for empty nonterminals with exact
+	  match nsec3 records.
+	- Fix for out of bounds integers, thanks to OSTIF audit.  It is in
+	  allocation debug code.
+	- Fix for auth zone nsec3 ent fix for wildcard nodata.
+
+25 March 2019: Wouter
+	- Fix that tls-session-ticket-keys: "" on its own in unbound.conf
+	  disables the tls session ticker key calls into the OpenSSL API.
+	- Fix crash if tls-servic-pem not filled in when necessary.
+
+21 March 2019: Wouter
+	- Fix #4240: Fix whitespace cleanup in example.conf.
+
+19 March 2019: Wouter
+	- add type CAA to libpyunbound (accessing libunbound from python).
+
+18 March 2019: Wouter
+	- Add log message, at verbosity 4, that says the query is encrypted
+	  with TLS, if that is enabled for the query.
+	- Fix #4239: set NOTIMPL when deny-any is enabled, for RFC8482.
+
+7 March 2019: Wouter
+	- Fix for #4233: guard use of NDEBUG, so that it can be passed in
+	  CFLAGS into configure.
+
+5 March 2019: Wouter
+	- Tag release 1.9.1rc1.  Which became 1.9.1 on 12 March 2019.  Trunk
+	  has 1.9.2 in development.
+
+1 March 2019: Wouter
+	- output forwarder log in ssl_req_order test.
+
+28 February 2019: Wouter
+	- Remove memory leak on pythonmod python2 script file init.
+	- Remove swig gcc8 python function cast warnings, they are ignored.
+	- Print correct module that failed when module-config is wrong.
+
+27 February 2019: Wouter
+	- Fix #4229: Unbound man pages lack information, about access-control
+	  order and local zone tags, and elements in views.
+	- Fix #14: contrib/unbound.init: Fix wrong comparison judgment
+	  before copying.
+	- Fix for python module on Windows, fix fopen.
+
+25 February 2019: Wouter
+	- Fix #4227: pair event del and add for libevent for tcp_req_info.
+
+21 February 2019: Wouter
+	- Fix the error for unknown module in module-config is understandable,
+	  and explains it was not compiled in and where to see the list.
+	- In example.conf explain where to put cachedb module in module-config.
+	- In man page and example config explain that most modules have to
+	  be listed at the start of module-config.
+
+20 February 2019: Wouter
+	- Fix pythonmod include and sockaddr_un ifdefs for compile on
+	  Windows, and for libunbound.
+
+18 February 2019: Wouter
+	- Print query name with ip_ratelimit exceeded log lines.
+	- Spaces instead of tabs in that log message.
+	- Print query name and IP address when domain rate limit exceeded.
+
+14 February 2019: Wouter
+	- Fix capsforid canonical sort qsort callback.
+
+11 February 2019: Wouter
+	- Note default for module-config in man page.
+	- Fix recursion lame test for qname minimisation asked queries,
+	  that were not present in the set of prepared answers.
+	- Fix #13: Remove left-over requirements on OpenSSL >= 1.1.0 for
+	  cert name matching, from man page.
+	- make depend, with newer gcc, nicer layout.
+
+7 February 2019: Wouter
+	- Fix #4206: OpenSSL 1.0.2 hostname verification for FreeBSD 11.2.
+	- Fix that qname minimisation does not skip a label when missing
+	  nameserver targets need to be fetched.
+	- Fix #4225: clients seem to erroneously receive no answer with
+	  DNS-over-TLS and qname-minimisation.
+
+4 February 2019: Wouter
+	- Fix that log-replies prints the correct name for local-alias
+	  names, for names that have a CNAME in local-data configuration.
+	  It logs the original query name, not the target of the CNAME.
+	- Add local-zone type inform_redirect, which logs like type inform,
+	  and redirects like type redirect.
+	- Perform canonical sort for 0x20 capsforid compare of replies,
+	  this sorts rrsets in the authority and additional section before
+	  comparison, so that out of order rrsets do not cause failure.
+
+31 January 2019: Wouter
+	- Set ub_ctx_set_tls call signature in ltrace config file for
+	  libunbound in contrib/libunbound.so.conf.
+	- improve documentation for tls-service-key and forward-first.
+	- #10: fixed pkg-config operations, PKG_PROG_PKG_CONFIG moved out of
+	  conditional section, fixes systemd builds, from Enrico Scholz.
+	- #9: For openssl 1.0.2 use the CRYPTO_THREADID locking callbacks,
+	  still supports the set_id_callback previous API.  And for 1.1.0
+	  no locking callbacks are needed.
+	- #8: Fix OpenSSL without ENGINE support compilation.
+	- Wipe TLS session key data from memory on exit.
+
+30 January 2019: Ralph
+	- Fix case in which query timeout can result in marking delegation
+	  as edns_lame_known.
+
+29 January 2019: Wouter
+	- Fix spelling of tls-ciphers in example.conf.in.
+	- Fix #4224: auth_xfr_notify.rpl test broken due to typo
+	- Fix locking for libunbound context setup with broken port config.
+
+28 January 2019: Wouter
+	- ub_ctx_set_tls call for libunbound that enables DoT for the machines
+	  set with ub_ctx_set_fwd.  Patch from Florian Obser.
+	- Set build system for added call in the libunbound API.
+	- List example config for root zone copy locally hosted with auth-zone
+	  as suggested from draft-ietf-dnsop-7706-bis-02.  But with updated
+	  B root address.
+	- set version to 1.9.0 for release.  And this was released with the
+	  spelling for tls-ciphers fix as 1.9.0 on Feb 5.  Trunk has 1.9.1 in
+	  development.
+
+25 January 2019: Wouter
+	- Fix that tcp for auth zone and outgoing does not remove and
+	  then gets the ssl read again applied to the deleted commpoint.
+	- updated contrib/fastrpz.patch to cleanly diff.
+	- no lock when threads disabled in tcp request buffer count.
+	- remove compile warnings from libnettle compile.
+	- output of newer lex 2.6.1 and bison 3.0.5.
+
+24 January 2019: Wouter
+	- Newer aclocal and libtoolize used for generating configure scripts,
+	  aclocal 1.16.1 and libtoolize 2.4.6.
+	- Fix unit test for python 3.7 new keyword 'async'.
+	- clang analysis fixes, assert arc4random buffer in init,
+	  no check for already checked delegation pointer in iterator,
+	  in testcode check for NULL packet matches, in perf do not copy
+	  from NULL start list when growing capacity.  Adjust host and file
+	  only when present in test header read to please checker.  In
+	  testcode for unknown macro operand give zero result. Initialise the
+	  passed argv array in test code.  In test code add EDNS data
+	  segment copy only when nonempty.
+	- Patch from Florian Obser fixes some compiler warnings:
+	  include mini_event.h to have a prototype for mini_ev_cmp
+	  include edns.h to have a prototype for apply_edns_options
+	  sldns_wire2str_edns_keepalive_print is only called in the wire2str,
+	  module declare it static to get rid of compiler warning:
+	  no previous prototype for function
+	  infra_find_ip_ratedata() is only called in the infra module,
+	  declare it static to get rid of compiler warning:
+	  no previous prototype for function
+	  do not shadow local variable buf in authzone
+	  auth_chunks_delete and az_nsec3_findnode are only called in the
+	  authzone module, declare them static to get rid of compiler warning:
+	  no previous prototype for function...
+	  copy_rrset() is only called in the respip module, declare it
+	  static to get rid of compiler warning:
+	  no previous prototype for function 'copy_rrset'
+	  no need for another variable "r"; gets rid of compiler warning:
+	  declaration shadows a local variable in libunbound.c
+	  no need for another variable "ns"; gets rid of compiler warning:
+	  declaration shadows a local variable in iterator.c
+	- Moved includes and make depend.
+
+23 January 2019: Wouter
+	- Patch from Manabu Sonoda with tls-ciphers and tls-ciphersuites
+	  options for unbound.conf.
+	- Fixes for the patch, and man page entry.
+	- Fix configure to detect SSL_CTX_set_ciphersuites, for better
+	  library compatibility when compiling.
+	- Patch for TLS session resumption from Manabu Sonoda,
+	  enable with tls-session-ticket-keys in unbound.conf.
+	- Fixes for patch (includes, declarations, warnings).  Free at end
+	  and keep config options in order read from file to keep the first
+	  one as the first one.
+	- Fix for IXFR fallback to reset counter when IXFR does not timeout.
+
+22 January 2019: Wouter
+	- Fix space calculation for tcp req buffer size.
+	- Doc for stream-wait-size and unit test.
+	- unbound-control stats has mem.streamwait that counts TCP and TLS
+	  waiting result buffers.
+	- Fix for #4219: secondaries not updated after serial change, unbound
+	  falls back to AXFR after IXFR gives several timeout failures.
+	- Fix that auth zone after IXFR fallback tries the same master.
+
+21 January 2019: Wouter
+	- Fix tcp idle timeout test, for difference in the tcp reply code.
+	- Unit test for tcp request reorder and timeouts.
+	- Unit tests for ssl out of order processing.
+	- Fix that multiple dns fragments can be carried in one TLS frame.
+	- Add stream-wait-size: 4m config option to limit the maximum
+	  memory used by waiting tcp and tls stream replies.  This avoids
+	  a denial of service where these replies use up all of the memory.
+
+17 January 2019: Wouter
+	- For caps-for-id fallback, use the whitelist to avoid timeout
+	  starting a fallback sequence for it.
+	- increase mesh max activation count for capsforid long fetches.
+
+16 January 2019: Ralph
+	- Get ready for the DNS flag day: remove EDNS lame procedure, do not
+	  re-query without EDNS after timeout.
+
+15 January 2019: Wouter
+	- In the out of order processing, reset byte count for (potential)
+	  partial read.
+	- Review fixes in out of order processing.
+
+14 January 2019: Wouter
+	- streamtcp option -a send queries consecutively and prints answers
+	  as they arrive.
+	- Fix for out of order processing administration quit cleanup.
+	- unit test for tcp out of order processing.
+
+11 January 2019: Wouter
+	- Initial commit for out-of-order processing for TCP and TLS.
+
+9 January 2019: Wouter
+	- Log query name for looping module errors.
+
+8 January 2019: Wouter
+	- Fix syntax in comment of local alias processing.
+	- Fix NSEC3 record that is returned in wildcard replies from
+	  auth-zone zones with NSEC3 and wildcards.
+
+7 January 2019: Wouter
+	- On FreeBSD warn if systcl settings do not allow server TCP FASTOPEN,
+	  and server tcp fastopen is enabled at compile time.
+	- Document interaction between the tls-upstream option in the server
+	  section and forward-tls-upstream option in the forward-zone sections.
+	- Add contrib/unbound-fuzzme.patch from Jacob Hoffman-Andrews,
+	  the patch adds a program used for fuzzing.
+
+12 December 2018: Wouter
+	- Fix for crash in dns64 module if response is null.
+
+10 December 2018: Wouter
+	- Fix config parser memory leaks.
+	- ip-ratelimit-factor of 1 allows all traffic through, instead of the
+	  previous blocking everything.
+	- Fix for FreeBSD port make with dnscrypt and dnstap enabled.
+	- Fix #4206: support openssl 1.0.2 for TLS hostname verification,
+	  alongside the 1.1.0 and later support that is already there.
+	- Fixup openssl 1.0.2 compile
+
+6 December 2018: Wouter
+	- Fix dns64 allocation in wrong region for returned internal queries.
+
+3 December 2018: Wouter
+	- Fix icon, no ragged edges and nicer resolutions available, for eg.
+	  Win 7 and Windows 10 display.
+	- cache-max-ttl also defines upperbound of initial TTL in response.
+
+30 November 2018: Wouter
+	- Patch for typo in unbound.conf man page.
+	- log-tag-queryreply: yes in unbound.conf tags the log-queries and
+	  log-replies in the log file for easier log filter maintenance.
+
+29 November 2018: Wouter
+	- iana portlist updated.
+	- Fix chroot auth-zone fix to remove chroot prefix.
+	- tag for 1.8.2rc1, which became 1.8.2 on 4 dec 2018, with icon
+	  updated.  Trunk contains 1.8.3 in development.
+	  Which became 1.8.3 on 11 december with only the dns64 fix of 6 dec.
+	  Trunk then became 1.8.4 in development.
+	- Fix that unbound-checkconf does not complains if the config file
+	  is not placed inside the chroot.
+	- Refuse to start with no ports.
+	- Remove clang analysis warnings.
+
+28 November 2018: Wouter
+	- Fix leak in chroot fix for auth-zone.
+	- Fix clang analysis for outside directory build test.
+
+27 November 2018: Wouter
+	- Fix DNS64 to not store intermediate results in cache, this avoids
+	  other threads from picking up the wrong data.  The module restores
+	  the previous no_cache_store setting when the the module is finished.
+	- Fix #4208: 'stub-no-cache' and 'forward-no-cache' not work.
+	- New and better fix for Fix #4193: Fix that prefetch failure does
+	  not overwrite valid cache entry with SERVFAIL.
+	- auth-zone give SERVFAIL when expired, fallback activates when
+	  expired, and this is documented in the man page.
+	- stat count SERVFAIL downstream auth-zone queries for expired zones.
+	- Put new logos into windows installer.
+	- Fix windows compile for new rrset roundrobin fix.
+	- Update contrib fastrpz patch for latest release.
+
+26 November 2018: Wouter
+	- Fix to not set GLOB_NOSORT so the unbound.conf include: files are
+	  sorted and in a predictable order.
+	- Fix #4193: Fix that prefetch failure does not overwrite valid cache
+	  entry with SERVFAIL.
+	- Add unbound-control view_local_datas command, like local_datas.
+	- Fix that unbound-control can send file for view_local_datas.
+
+22 November 2018: Wouter
+	- With ./configure --with-pyunbound --with-pythonmodule
+	  PYTHON_VERSION=3.6 or with 2.7 unbound can compile and unit tests
+	  succeed for the python module.
+	- pythonmod logs the python error and traceback on failure.
+	- ignore debug python module for test in doxygen output.
+	- review fixes for python module.
+	- Fix #4209: Crash in libunbound when called from getdns.
+	- auth zone zonefiles can be in a chroot, the chroot directory
+	  components are removed before use.
+	- Fix that empty zonefile means the zonefile is not set and not used.
+	- make depend.
+
+21 November 2018: Wouter
+	- Scrub NS records from NODATA responses as well.
+
+20 November 2018: Wouter
+	- Scrub NS records from NXDOMAIN responses to stop fragmentation
+	  poisoning of the cache.
+	- Add patch from Jan Vcelak for pythonmod,
+	  add sockaddr_storage getters, add support for query callbacks,
+	  allow raw address access via comm_reply and update API documentation.
+	- Removed compile warnings in pythonmod sockaddr routines.
+
+19 November 2018: Wouter
+	- Support SO_REUSEPORT_LB in FreeBSD 12 with the so-reuseport: yes
+	  option in unbound.conf.
+
+6 November 2018: Ralph
+	- Bugfix min-client-subnet-ipv6
+
+25 October 2018: Ralph
+	- Add min-client-subnet-ipv6 and min-client-subnet-ipv4 options.
+
+25 October 2018: Wouter
+	- Fix #4191: NXDOMAIN vs SERVFAIL during dns64 PTR query.
+	- Fix #4190: Please create a "ANY" deny option, adds the option
+	  deny-any: yes in unbound.conf.  This responds with an empty message
+	  to queries of type ANY.
+	- Fix #4141: More randomness to rrset-roundrobin.
+	- Fix #4132: Openness/closeness of RANGE intervals in rpl files.
+	- Fix #4126: RTT_band too low on VSAT links with 600+ms latency,
+	  adds the option unknown-server-time-limit to unbound.conf that
+	  can be increased to avoid the problem.
+	- remade makefile dependencies.
+	- Fix #4152: Logs shows wrong time when using log-time-ascii: yes.
+
+24 October 2018: Ralph
+	- Add markdel function to ECS slabhash.
+	- Limit ECS scope returned to client to the scope used for caching.
+	- Make lint like previous #4154 fix.
+
+22 October 2018: Wouter
+	- Fix #4192: unbound-control-setup generates keys not readable by
+	  group.
+	- check that the dnstap socket file can be opened and exists, print
+	  error if not.
+	- Fix #4154: make ECS_MAX_TREESIZE configurable, with
+	  the max-ecs-tree-size-ipv4 and max-ecs-tree-size-ipv6 options.
+
+22 October 2018: Ralph
+	- Change fast-server-num default to 3.
+
+8 October 2018: Ralph
+	- Add fast-server-permil and fast-server-num options.
+	- Deprecate low-rtt and low-rtt-permil options.
+
 8 October 2018: Wouter
-	- fastrpz.patch fix included.
+	- Squelch log of failed to tcp initiate after TCP Fastopen failure.
 
+5 October 2018: Wouter
+	- Squelch EADDRNOTAVAIL errors when the interface goes away,
+	  this omits 'can't assign requested address' errors unless
+	  verbosity is set to a high value.
+	- Set default for so-reuseport to no for FreeBSD.  It is enabled
+	  by default for Linux and DragonFlyBSD.  The setting can 
+	  be configured in unbound.conf to override the default.
+	- iana port update.
+
+2 October 2018: Wouter
+	- updated contrib/fastrpz.patch to apply for this version
+	- dnscrypt.c removed sizeof to get array bounds.
+	- Fix testlock code to set noreturn on error routine.
+	- Remove unused variable from contrib fastrpz/rpz.c and
+	  remove unused diagnostic pragmas that themselves generate warnings
+	- clang analyze test is used only when assertions are enabled.
+
 1 October 2018: Wouter
-	- tag for release 1.8.1rc1.
+	- tag for release 1.8.1rc1.  Became release 1.8.1 on 8 oct, with
+	  fastrpz.patch fix included.  Trunk has 1.8.2 in development.
 
 27 September 2018: Wouter
 	- Fix #4188: IPv6 forwarders without ipv6 result in SERVFAIL, fixes
--- contrib/unbound/doc/README.orig
+++ contrib/unbound/doc/README
@@ -1,4 +1,4 @@
-README for Unbound 1.8.1
+README for Unbound 1.10.1
 Copyright 2007 NLnet Labs
 http://unbound.net
 
@@ -99,7 +99,7 @@
   the config file is an alternative. The interface-automatic option uses
   non portable socket options, Linux and FreeBSD should work fine.
 o The warning 'openssl has no entropy, seeding with time', with chroot 
-  enabled, may be solved with a symbolic link to /dev/random from <chrootdir>.
+  enabled, may be solved with a symbolic link to /dev/urandom from <chrootdir>.
 o On Solaris 5.10 some libtool packages from repositories do not work with
   gcc, showing errors gcc: unrecognized option `-KPIC'
   To solve this do ./configure libtool=./libtool [your options...].
--- contrib/unbound/doc/README.ipset.md.orig
+++ contrib/unbound/doc/README.ipset.md
@@ -0,0 +1,65 @@
+## Created a module to support the ipset that could add the domain's ip to a list easily.
+
+### Purposes:
+* In my case, I can't access the facebook, twitter, youtube and thousands web site for some reason. VPN is a solution. But the internet too slow whether all traffics pass through the vpn.
+So, I set up a transparent proxy to proxy the traffic which has been blocked only.
+At the final step, I need to install a dns service which would work with ipset well to launch the system.
+I did some research for this. Unfortunately, Unbound, My favorite dns service doesn't support ipset yet. So, I decided to implement it by my self and contribute the patch. It's good for me and the community.
+```
+# unbound.conf
+server:
+  ...
+  local-zone: "facebook.com" ipset
+  local-zone: "twitter.com" ipset
+  local-zone: "instagram.com" ipset
+  more social website
+
+ipset:
+  name-v4: "gfwlist"
+```
+```
+# iptables
+iptables -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800
+iptables -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800
+```
+
+* This patch could work with iptables rules to batch block the IPs.
+```
+# unbound.conf
+server:
+  ...
+  local-zone: "facebook.com" ipset
+  local-zone: "twitter.com" ipset
+  local-zone: "instagram.com" ipset
+  more social website
+
+ipset:
+  name-v4: "blacklist"
+  name-v6: "blacklist6"
+```
+```
+# iptables
+iptables -A INPUT -m set --set blacklist src -j DROP
+ip6tables -A INPUT -m set --set blacklist6 src -j DROP
+```
+
+### Notes:
+* To enable this module the root privileges is required.
+* Please create a set with ipset command first. eg. **ipset -N blacklist iphash**
+
+### How to use:
+```
+./configure --enable-ipset
+make && make install
+```
+
+### Configuration:
+```
+# unbound.conf
+server:
+  ...
+  local-zone: "example.com" ipset
+
+ipset:
+  name-v4: "blacklist"
+```
--- contrib/unbound/doc/TODO.orig
+++ contrib/unbound/doc/TODO
@@ -29,7 +29,7 @@
 o add local-file: config with authority features.
 o (option) to make local-data answers be secure for libunbound (default=no)
 o (option) to make chroot: copy all needed files into jail (or make jail)
-	perhaps also print reminder to link /dev/random and sysloghack.
+	perhaps also print reminder to link /dev/urandom and sysloghack.
 o overhaul outside-network servicedquery to merge with udpwait and tcpwait,
   to make timers in servicedquery independent of udpwait queues.
 o check into rebinding ports for efficiency, configure time test.
--- contrib/unbound/doc/example.conf.orig
+++ contrib/unbound/doc/example.conf
@@ -1,7 +1,7 @@
 #
 # Example configuration file.
 #
-# See unbound.conf(5) man page, version 1.8.1.
+# See unbound.conf(5) man page, version 1.9.2.
 #
 # this is a comment.
 
@@ -103,6 +103,7 @@
 	# so-sndbuf: 0
 
 	# use SO_REUSEPORT to distribute queries over threads.
+	# at extreme load it could be better to turn it off to distribute even.
 	# so-reuseport: yes
 
 	# use IP_TRANSPARENT so the interface: addresses can be non-local
@@ -123,6 +124,9 @@
 	# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
 	# max-udp-size: 4096
 
+	# max memory to use for stream(tcp and tls) waiting result buffers.
+	# stream-wait-size: 4m
+
 	# buffer size for handling DNS data. No messages larger than this
 	# size can be sent or received, by UDP or TCP. In bytes.
 	# msg-buffer-size: 65552
@@ -145,6 +149,10 @@
 	# msec to wait before close of port on timeout UDP. 0 disables.
 	# delay-close: 0
 
+	# msec for waiting for an unknown server to reply.  Increase if you
+	# are behind a slow satellite link, to eg. 1128.
+	# unknown-server-time-limit: 376
+
 	# the amount of memory to use for the RRset cache.
 	# plain value in bytes or you can append k, m or G. default is "4Mb".
 	# rrset-cache-size: 4m
@@ -318,6 +326,10 @@
 	# timetoresolve, fromcache and responsesize.
 	# log-replies: no
 
+	# log with tag 'query' and 'reply' instead of 'info' for
+	# filtering log-queries and log-replies from the log.
+	# log-tag-queryreply: no
+
 	# log the local-zone actions, like local-zone type inform is enabled
 	# also for the other local zone types.
 	# log-local-actions: no
@@ -449,6 +461,9 @@
 	# if yes, perform key lookups adjacent to normal lookups.
 	# prefetch-key: no
 
+	# deny queries of type ANY with an empty response.
+	# deny-any: no
+
 	# if yes, Unbound rotates RRSet order in response.
 	# rrset-roundrobin: no
 
@@ -461,6 +476,9 @@
 
 	# module configuration of the server. A string with identifiers
 	# separated by spaces. Syntax: "[dns64] [validator] iterator"
+	# most modules have to be listed at the beginning of the line,
+	# except cachedb(just before iterator), and python (at the beginning,
+	# or, just before the iterator).
 	# module-config: "validator iterator"
 
 	# File with trusted keys, kept uptodate using RFC5011 probes,
@@ -475,7 +493,7 @@
 
 	# trust anchor signaling sends a RFC8145 key tag query after priming.
 	# trust-anchor-signaling: yes
-	
+
 	# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
 	# root-key-sentinel: yes
 
@@ -659,6 +677,7 @@
 	# o typetransparent resolves normally for other types and other names
 	# o inform acts like transparent, but logs client IP address
 	# o inform_deny drops queries and logs client IP address
+	# o inform_redirect redirects queries and logs client IP address
 	# o always_transparent, always_refuse, always_nxdomain, resolve in
 	#   that way but ignore local data for that name
 	# o noview breaks out of that view towards global local-zones.
@@ -701,6 +720,19 @@
 	# tls-service-pem: "path/to/publiccertfile.pem"
 	# tls-port: 853
 
+	# cipher setting for TLSv1.2
+	# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
+	# cipher setting for TLSv1.3
+	# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
+
+	# Add the secret file for TLS Session Ticket.
+	# Secret file must be 80 bytes of random data.
+	# First key use to encrypt and decrypt TLS session tickets.
+	# Other keys use to decrypt only.
+	# requires restart to take effect.
+	# tls-session-ticket-keys: "path/to/secret_file1"
+	# tls-session-ticket-keys: "path/to/secret_file2"
+
 	# request upstream over TLS (with plain DNS inside the TLS stream).
 	# Default is no.  Can be turned on and off with unbound-control.
 	# tls-upstream: no
@@ -757,11 +789,11 @@
 	# Limit the number of connections simultaneous from a netblock
 	# tcp-connection-limit: 192.0.2.0/24 12
 
-	# what is considered a low rtt (ping time for upstream server), in msec
-	# low-rtt: 45
-	# select low rtt this many times out of 1000. 0 means the fast server
-	# select is disabled.  prefetches are not sped up.
-	# low-rtt-permil: 0
+	# select from the fastest servers this many times out of 1000. 0 means
+	# the fast server select is disabled. prefetches are not sped up.
+	# fast-server-permil: 0
+	# the number of servers that will be used in the fast server selection.
+	# fast-server-num: 3
 
 	# Specific options for ipsecmod. unbound needs to be configured with
 	# --enable-ipsecmod for these to take effect.
@@ -795,6 +827,8 @@
 # Python config section. To enable:
 # o use --with-pythonmodule to configure before compiling.
 # o list python in the module-config string (above) to enable.
+#   It can be at the start, it gets validated results, or just before
+#   the iterator and process before DNSSEC validation.
 # o and give a python-script to run.
 python:
 	# Script file to load
@@ -879,15 +913,25 @@
 # notifies.
 # auth-zone:
 #	name: "."
+#	master: 199.9.14.201         # b.root-servers.net
+#	master: 192.33.4.12          # c.root-servers.net
+#	master: 199.7.91.13          # d.root-servers.net
+#	master: 192.5.5.241          # f.root-servers.net
+#	master: 192.112.36.4         # g.root-servers.net
+#	master: 193.0.14.129         # k.root-servers.net
+#	master: 192.0.47.132         # xfr.cjr.dns.icann.org
+#	master: 192.0.32.132         # xfr.lax.dns.icann.org
+#	master: 2001:500:200::b      # b.root-servers.net
+#	master: 2001:500:2::c        # c.root-servers.net
+#	master: 2001:500:2d::d       # d.root-servers.net
+#	master: 2001:500:2f::f       # f.root-servers.net
+#	master: 2001:500:12::d0d     # g.root-servers.net
+#	master: 2001:7fd::1          # k.root-servers.net
+#	master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
+#	master: 2620:0:2d0:202::132  # xfr.lax.dns.icann.org
+#	fallback-enabled: yes
 #	for-downstream: no
 #	for-upstream: yes
-#	fallback-enabled: yes
-#	master: b.root-servers.net
-#	master: c.root-servers.net
-#	master: e.root-servers.net
-#	master: f.root-servers.net
-#	master: g.root-servers.net
-#	master: k.root-servers.net
 # auth-zone:
 #	name: "example.org"
 #	for-downstream: yes
@@ -935,7 +979,7 @@
 # Enable external backend DB as auxiliary cache.  Specify the backend name
 # (default is "testframe", which has no use other than for debugging and
 # testing) and backend-specific options.  The 'cachedb' module must be
-# included in module-config.
+# included in module-config, just before the iterator module.
 # cachedb:
 #     backend: "testframe"
 #     # secret seed string to calculate hashed keys
--- contrib/unbound/doc/example.conf.in.orig
+++ contrib/unbound/doc/example.conf.in
@@ -1,7 +1,7 @@
 #
 # Example configuration file.
 #
-# See unbound.conf(5) man page, version 1.8.1.
+# See unbound.conf(5) man page, version 1.10.1.
 #
 # this is a comment.
 
@@ -103,6 +103,7 @@
 	# so-sndbuf: 0
 
 	# use SO_REUSEPORT to distribute queries over threads.
+	# at extreme load it could be better to turn it off to distribute even.
 	# so-reuseport: yes
 
 	# use IP_TRANSPARENT so the interface: addresses can be non-local
@@ -123,6 +124,9 @@
 	# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
 	# max-udp-size: 4096
 
+	# max memory to use for stream(tcp and tls) waiting result buffers.
+	# stream-wait-size: 4m
+
 	# buffer size for handling DNS data. No messages larger than this
 	# size can be sent or received, by UDP or TCP. In bytes.
 	# msg-buffer-size: 65552
@@ -145,6 +149,10 @@
 	# msec to wait before close of port on timeout UDP. 0 disables.
 	# delay-close: 0
 
+	# msec for waiting for an unknown server to reply.  Increase if you
+	# are behind a slow satellite link, to eg. 1128.
+	# unknown-server-time-limit: 376
+
 	# the amount of memory to use for the RRset cache.
 	# plain value in bytes or you can append k, m or G. default is "4Mb".
 	# rrset-cache-size: 4m
@@ -278,7 +286,7 @@
 	# The pid file can be absolute and outside of the chroot, it is
 	# written just prior to performing the chroot and dropping permissions.
 	#
-	# Additionally, unbound may need to access /dev/random (for entropy).
+	# Additionally, unbound may need to access /dev/urandom (for entropy).
 	# How to do this is specific to your OS.
 	#
 	# If you give "" no chroot is performed. The path must not end in a /.
@@ -318,6 +326,10 @@
 	# timetoresolve, fromcache and responsesize.
 	# log-replies: no
 
+	# log with tag 'query' and 'reply' instead of 'info' for
+	# filtering log-queries and log-replies from the log.
+	# log-tag-queryreply: no
+
 	# log the local-zone actions, like local-zone type inform is enabled
 	# also for the other local zone types.
 	# log-local-actions: no
@@ -449,6 +461,9 @@
 	# if yes, perform key lookups adjacent to normal lookups.
 	# prefetch-key: no
 
+	# deny queries of type ANY with an empty response.
+	# deny-any: no
+
 	# if yes, Unbound rotates RRSet order in response.
 	# rrset-roundrobin: no
 
@@ -461,6 +476,9 @@
 
 	# module configuration of the server. A string with identifiers
 	# separated by spaces. Syntax: "[dns64] [validator] iterator"
+	# most modules have to be listed at the beginning of the line,
+	# except cachedb(just before iterator), and python (at the beginning,
+	# or, just before the iterator).
 	# module-config: "validator iterator"
 
 	# File with trusted keys, kept uptodate using RFC5011 probes,
@@ -475,7 +493,7 @@
 
 	# trust anchor signaling sends a RFC8145 key tag query after priming.
 	# trust-anchor-signaling: yes
-	
+
 	# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
 	# root-key-sentinel: yes
 
@@ -540,8 +558,8 @@
 	# that set CD but cannot validate themselves.
 	# ignore-cd-flag: no
 
-	# Serve expired responses from cache, with TTL 0 in the response,
-	# and then attempt to fetch the data afresh.
+	# Serve expired responses from cache, with serve-expired-reply-ttl in
+	# the response, and then attempt to fetch the data afresh.
 	# serve-expired: no
 	#
 	# Limit serving of expired responses to configured seconds after
@@ -553,6 +571,16 @@
 	# that the expired records will be served as long as there are queries
 	# for it.
 	# serve-expired-ttl-reset: no
+	#
+	# TTL value to use when replying with expired data.
+	# serve-expired-reply-ttl: 30
+	#
+	# Time in milliseconds before replying to the client with expired data.
+	# This essentially enables the serve-stale behavior as specified in
+	# draft-ietf-dnsop-serve-stale-10 that first tries to resolve before
+	# immediately responding with expired data.  0 disables this behavior.
+	# A recommended value is 1800.
+	# serve-expired-client-timeout: 0
 
 	# Have the validator log failed validations for your diagnosis.
 	# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
@@ -636,6 +664,9 @@
 	# local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault
 	# And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa.
 
+	# Add example.com into ipset
+	# local-zone: "example.com" ipset
+
 	# If unbound is running service for the local host then it is useful
 	# to perform lan-wide lookups to the upstream, and unblock the
 	# long list of local-zones above.  If this unbound is a dns server
@@ -659,6 +690,7 @@
 	# o typetransparent resolves normally for other types and other names
 	# o inform acts like transparent, but logs client IP address
 	# o inform_deny drops queries and logs client IP address
+	# o inform_redirect redirects queries and logs client IP address
 	# o always_transparent, always_refuse, always_nxdomain, resolve in
 	#   that way but ignore local data for that name
 	# o noview breaks out of that view towards global local-zones.
@@ -701,6 +733,19 @@
 	# tls-service-pem: "path/to/publiccertfile.pem"
 	# tls-port: 853
 
+	# cipher setting for TLSv1.2
+	# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
+	# cipher setting for TLSv1.3
+	# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
+
+	# Add the secret file for TLS Session Ticket.
+	# Secret file must be 80 bytes of random data.
+	# First key use to encrypt and decrypt TLS session tickets.
+	# Other keys use to decrypt only.
+	# requires restart to take effect.
+	# tls-session-ticket-keys: "path/to/secret_file1"
+	# tls-session-ticket-keys: "path/to/secret_file2"
+
 	# request upstream over TLS (with plain DNS inside the TLS stream).
 	# Default is no.  Can be turned on and off with unbound-control.
 	# tls-upstream: no
@@ -757,11 +802,11 @@
 	# Limit the number of connections simultaneous from a netblock
 	# tcp-connection-limit: 192.0.2.0/24 12
 
-	# what is considered a low rtt (ping time for upstream server), in msec
-	# low-rtt: 45
-	# select low rtt this many times out of 1000. 0 means the fast server
-	# select is disabled.  prefetches are not sped up.
-	# low-rtt-permil: 0
+	# select from the fastest servers this many times out of 1000. 0 means
+	# the fast server select is disabled. prefetches are not sped up.
+	# fast-server-permil: 0
+	# the number of servers that will be used in the fast server selection.
+	# fast-server-num: 3
 
 	# Specific options for ipsecmod. unbound needs to be configured with
 	# --enable-ipsecmod for these to take effect.
@@ -795,6 +840,8 @@
 # Python config section. To enable:
 # o use --with-pythonmodule to configure before compiling.
 # o list python in the module-config string (above) to enable.
+#   It can be at the start, it gets validated results, or just before
+#   the iterator and process before DNSSEC validation.
 # o and give a python-script to run.
 python:
 	# Script file to load
@@ -879,15 +926,25 @@
 # notifies.
 # auth-zone:
 #	name: "."
+#	master: 199.9.14.201         # b.root-servers.net
+#	master: 192.33.4.12          # c.root-servers.net
+#	master: 199.7.91.13          # d.root-servers.net
+#	master: 192.5.5.241          # f.root-servers.net
+#	master: 192.112.36.4         # g.root-servers.net
+#	master: 193.0.14.129         # k.root-servers.net
+#	master: 192.0.47.132         # xfr.cjr.dns.icann.org
+#	master: 192.0.32.132         # xfr.lax.dns.icann.org
+#	master: 2001:500:200::b      # b.root-servers.net
+#	master: 2001:500:2::c        # c.root-servers.net
+#	master: 2001:500:2d::d       # d.root-servers.net
+#	master: 2001:500:2f::f       # f.root-servers.net
+#	master: 2001:500:12::d0d     # g.root-servers.net
+#	master: 2001:7fd::1          # k.root-servers.net
+#	master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
+#	master: 2620:0:2d0:202::132  # xfr.lax.dns.icann.org
+#	fallback-enabled: yes
 #	for-downstream: no
 #	for-upstream: yes
-#	fallback-enabled: yes
-#	master: b.root-servers.net
-#	master: c.root-servers.net
-#	master: e.root-servers.net
-#	master: f.root-servers.net
-#	master: g.root-servers.net
-#	master: k.root-servers.net
 # auth-zone:
 #	name: "example.org"
 #	for-downstream: yes
@@ -935,7 +992,7 @@
 # Enable external backend DB as auxiliary cache.  Specify the backend name
 # (default is "testframe", which has no use other than for debugging and
 # testing) and backend-specific options.  The 'cachedb' module must be
-# included in module-config.
+# included in module-config, just before the iterator module.
 # cachedb:
 #     backend: "testframe"
 #     # secret seed string to calculate hashed keys
@@ -948,3 +1005,31 @@
 #     redis-server-port: 6379
 #     # timeout (in ms) for communication with the redis server
 #     redis-timeout: 100
+
+# IPSet
+# Add specify domain into set via ipset.
+# Note: To enable ipset needs run unbound as root user.
+# ipset:
+#     # set name for ip v4 addresses
+#     name-v4: "list-v4"
+#     # set name for ip v6 addresses
+#     name-v6: "list-v6"
+#
+
+# Response Policy Zones
+# RPZ policies. Applied in order of configuration. QNAME and Response IP
+# Address trigger are the only supported triggers. Supported actions are:
+# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Policies can be loaded from
+# file, using zone transfer, or using HTTP. The respip module needs to be added
+# to the module-config, e.g.: module-config: "respip validator iterator".
+# rpz:
+#     name: "rpz.example.com"
+#     zonefile: "rpz.example.com"
+#     master: 192.0.2.0
+#     allow-notify: 192.0.2.0/32
+#     url: http://www.example.com/rpz.example.org.zone
+#     rpz-action-override: cname
+#     rpz-cname-override: www.example.org
+#     rpz-log: yes
+#     rpz-log-name: "example policy"
+#     tags: "example"
--- contrib/unbound/doc/libunbound.3.orig
+++ contrib/unbound/doc/libunbound.3
@@ -1,4 +1,4 @@
-.TH "libunbound" "3" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "libunbound" "3" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2"
 .\"
 .\" libunbound.3 -- unbound library functions manual
 .\"
@@ -20,6 +20,7 @@
 .B ub_ctx_config,
 .B ub_ctx_set_fwd,
 .B ub_ctx_set_stub,
+.B ub_ctx_set_tls,
 .B ub_ctx_resolvconf,
 .B ub_ctx_hosts,
 .B ub_ctx_add_ta,
@@ -43,7 +44,7 @@
 .B ub_ctx_zone_remove,
 .B ub_ctx_data_add,
 .B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.8.1 functions.
+\- Unbound DNS validating resolver 1.9.2 functions.
 .SH "SYNOPSIS"
 .B #include <unbound.h>
 .LP
@@ -72,6 +73,9 @@
 		\fIint\fR isprime);
 .LP
 \fIint\fR
+\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls);
+.LP
+\fIint\fR
 \fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
 .LP
 \fIint\fR
@@ -227,6 +231,12 @@
 At this time it is only possible to set configuration before the
 first resolve is done.
 .TP
+.B ub_ctx_set_tls
+Enable DNS over TLS (DoT) for machines set with 
+.B ub_ctx_set_fwd.
+At this time it is only possible to set configuration before the
+first resolve is done.
+.TP
 .B ub_ctx_resolvconf
 By default the root servers are queried and full resolver mode is used, but
 you can use this call to read the list of nameservers to use from the
--- contrib/unbound/doc/libunbound.3.in.orig
+++ contrib/unbound/doc/libunbound.3.in
@@ -1,4 +1,4 @@
-.TH "libunbound" "3" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "libunbound" "3" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
 .\"
 .\" libunbound.3 -- unbound library functions manual
 .\"
@@ -20,6 +20,7 @@
 .B ub_ctx_config,
 .B ub_ctx_set_fwd,
 .B ub_ctx_set_stub,
+.B ub_ctx_set_tls,
 .B ub_ctx_resolvconf,
 .B ub_ctx_hosts,
 .B ub_ctx_add_ta,
@@ -43,7 +44,7 @@
 .B ub_ctx_zone_remove,
 .B ub_ctx_data_add,
 .B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.8.1 functions.
+\- Unbound DNS validating resolver 1.10.1 functions.
 .SH "SYNOPSIS"
 .B #include <unbound.h>
 .LP
@@ -72,6 +73,9 @@
 		\fIint\fR isprime);
 .LP
 \fIint\fR
+\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls);
+.LP
+\fIint\fR
 \fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
 .LP
 \fIint\fR
@@ -227,6 +231,12 @@
 At this time it is only possible to set configuration before the
 first resolve is done.
 .TP
+.B ub_ctx_set_tls
+Enable DNS over TLS (DoT) for machines set with 
+.B ub_ctx_set_fwd.
+At this time it is only possible to set configuration before the
+first resolve is done.
+.TP
 .B ub_ctx_resolvconf
 By default the root servers are queried and full resolver mode is used, but
 you can use this call to read the list of nameservers to use from the
@@ -386,12 +396,13 @@
 		char* canonname; /* canonical name of result */
 		int rcode;   /* additional error code in case of no data */
 		void* answer_packet; /* full network format answer packet */
-		int answer_len; /* length of packet in octets */
+		int answer_len;  /* length of packet in octets */
 		int havedata; /* true if there is data */
 		int nxdomain; /* true if nodata because name does not exist */
-		int secure;  /* true if result is secure */
-		int bogus;   /* true if a security failure happened */
+		int secure;   /* true if result is secure */
+		int bogus;    /* true if a security failure happened */
 		char* why_bogus; /* string with error if bogus */
+		int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
 		int ttl;     /* number of seconds the result is valid */
 	};
 .fi
--- contrib/unbound/doc/unbound-anchor.8.orig
+++ contrib/unbound/doc/unbound-anchor.8
@@ -1,4 +1,4 @@
-.TH "unbound-anchor" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound-anchor" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2"
 .\"
 .\" unbound-anchor.8 -- unbound anchor maintenance utility manual
 .\"
--- contrib/unbound/doc/unbound-anchor.8.in.orig
+++ contrib/unbound/doc/unbound-anchor.8.in
@@ -1,4 +1,4 @@
-.TH "unbound-anchor" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound-anchor" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
 .\"
 .\" unbound-anchor.8 -- unbound anchor maintenance utility manual
 .\"
@@ -69,6 +69,10 @@
 The default is "data.iana.org".  It connects to the port specified with \-P.
 You can pass an IPv4 address or IPv6 address (no brackets) if you want.
 .TP
+.B \-b \fIaddress
+The source address to bind to for domain resolution and contacting the server
+on https.  May be either an IPv4 address or IPv6 address (no brackets).
+.TP
 .B \-x \fIpath
 The pathname to the root\-anchors.xml file on the server. (forms URL with \-u).
 The default is /root\-anchors/root\-anchors.xml.
--- contrib/unbound/doc/unbound-checkconf.8.orig
+++ contrib/unbound/doc/unbound-checkconf.8
@@ -1,4 +1,4 @@
-.TH "unbound-checkconf" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound-checkconf" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2"
 .\"
 .\" unbound-checkconf.8 -- unbound configuration checker manual
 .\"
--- contrib/unbound/doc/unbound-checkconf.8.in.orig
+++ contrib/unbound/doc/unbound-checkconf.8.in
@@ -1,4 +1,4 @@
-.TH "unbound-checkconf" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound-checkconf" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
 .\"
 .\" unbound-checkconf.8 -- unbound configuration checker manual
 .\"
--- contrib/unbound/doc/unbound-control.8.orig
+++ contrib/unbound/doc/unbound-control.8
@@ -1,4 +1,4 @@
-.TH "unbound-control" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound-control" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2"
 .\"
 .\" unbound-control.8 -- unbound remote control manual
 .\"
@@ -322,6 +322,9 @@
 .TP
 .B view_local_data_remove \fIview\fR \fIname
 \fIlocal_data_remove\fR for given view.
+.TP
+.B view_local_datas \fIview\fR
+Add a list of \fIlocal_data\fR for given view from stdin.  Like local_datas.
 .SH "EXIT CODE"
 The unbound\-control program exits with status code 1 on error, 0 on success.
 .SH "SET UP"
@@ -496,6 +499,10 @@
 Memory in bytes in use by the validator module. Includes the key cache and
 negative cache.
 .TP
+.I mem.streamwait
+Memory in bytes in used by the TCP and TLS stream wait buffers.  These are
+answers waiting to be written back to the clients.
+.TP
 .I histogram.<sec>.<usec>.to.<sec>.<usec>
 Shows a histogram, summed over all threads. Every element counts the
 recursive queries whose reply time fit between the lower and upper bound.
@@ -531,6 +538,10 @@
 Number of queries that were made using TLS towards the unbound server.
 These are also counted in num.query.tcp, because TLS uses TCP.
 .TP
+.I num.query.tls.resume
+Number of TLS session resumptions, these are queries over TLS towards
+the unbound server where the client negotiated a TLS session resumption key.
+.TP
 .I num.query.ipv6
 Number of queries that were made using IPv6 towards the unbound server.
 .TP
--- contrib/unbound/doc/unbound-control.8.in.orig
+++ contrib/unbound/doc/unbound-control.8.in
@@ -1,4 +1,4 @@
-.TH "unbound-control" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound-control" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
 .\"
 .\" unbound-control.8 -- unbound remote control manual
 .\"
@@ -322,6 +322,12 @@
 .TP
 .B view_local_data_remove \fIview\fR \fIname
 \fIlocal_data_remove\fR for given view.
+.TP
+.B view_local_datas_remove \fIview\fR
+Remove a list of \fIlocal_data\fR for given view from stdin. Like local_datas_remove.
+.TP
+.B view_local_datas \fIview\fR
+Add a list of \fIlocal_data\fR for given view from stdin.  Like local_datas.
 .SH "EXIT CODE"
 The unbound\-control program exits with status code 1 on error, 0 on success.
 .SH "SET UP"
@@ -376,8 +382,8 @@
 Not part of the recursivereplies (or the histogram thereof) or cachemiss,
 as a cache response was sent.
 .TP
-.I threadX.num.zero_ttl
-number of replies with ttl zero, because they served an expired cache entry.
+.I threadX.num.expired
+number of replies that served an expired cache entry.
 .TP
 .I threadX.num.recursivereplies
 The number of replies sent to queries that needed recursive processing. Could be smaller than threadX.num.cachemiss if due to timeouts no replies were sent for some queries.
@@ -440,7 +446,7 @@
 .I total.num.prefetch
 summed over threads.
 .TP
-.I total.num.zero_ttl
+.I total.num.expired
 summed over threads.
 .TP
 .I total.num.recursivereplies
@@ -496,6 +502,10 @@
 Memory in bytes in use by the validator module. Includes the key cache and
 negative cache.
 .TP
+.I mem.streamwait
+Memory in bytes in used by the TCP and TLS stream wait buffers.  These are
+answers waiting to be written back to the clients.
+.TP
 .I histogram.<sec>.<usec>.to.<sec>.<usec>
 Shows a histogram, summed over all threads. Every element counts the
 recursive queries whose reply time fit between the lower and upper bound.
@@ -531,6 +541,10 @@
 Number of queries that were made using TLS towards the unbound server.
 These are also counted in num.query.tcp, because TLS uses TCP.
 .TP
+.I num.query.tls.resume
+Number of TLS session resumptions, these are queries over TLS towards
+the unbound server where the client negotiated a TLS session resumption key.
+.TP
 .I num.query.ipv6
 Number of queries that were made using IPv6 towards the unbound server.
 .TP
@@ -649,6 +663,11 @@
 Number of queries answered from the edns client subnet cache.  These are
 counted as cachemiss by the main counters, but hit the client subnet
 specific cache, after getting processed by the edns client subnet module.
+.TP
+.I num.rpz.action.<rpz_action>
+Number of queries answered using configured RPZ policy, per RPZ action type.
+Possible actions are: nxdomain, nodata, passthru, drop, local_data, disabled,
+and cname_override.
 .SH "FILES"
 .TP
 .I @ub_conf_file@
--- contrib/unbound/doc/unbound-host.1.orig
+++ contrib/unbound/doc/unbound-host.1
@@ -1,4 +1,4 @@
-.TH "unbound\-host" "1" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound\-host" "1" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2"
 .\"
 .\" unbound-host.1 -- unbound DNS lookup utility
 .\"
--- contrib/unbound/doc/unbound-host.1.in.orig
+++ contrib/unbound/doc/unbound-host.1.in
@@ -1,4 +1,4 @@
-.TH "unbound\-host" "1" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound\-host" "1" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
 .\"
 .\" unbound-host.1 -- unbound DNS lookup utility
 .\"
--- contrib/unbound/doc/unbound.8.orig
+++ contrib/unbound/doc/unbound.8
@@ -1,4 +1,4 @@
-.TH "unbound" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound" "8" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2"
 .\"
 .\" unbound.8 -- unbound manual
 .\"
@@ -9,7 +9,7 @@
 .\"
 .SH "NAME"
 .B unbound
-\- Unbound DNS validating resolver 1.8.1.
+\- Unbound DNS validating resolver 1.9.2.
 .SH "SYNOPSIS"
 .B unbound
 .RB [ \-h ]
--- contrib/unbound/doc/unbound.8.in.orig
+++ contrib/unbound/doc/unbound.8.in
@@ -1,4 +1,4 @@
-.TH "unbound" "8" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
 .\"
 .\" unbound.8 -- unbound manual
 .\"
@@ -9,7 +9,7 @@
 .\"
 .SH "NAME"
 .B unbound
-\- Unbound DNS validating resolver 1.8.1.
+\- Unbound DNS validating resolver 1.10.1.
 .SH "SYNOPSIS"
 .B unbound
 .RB [ \-h ]
@@ -54,7 +54,7 @@
 The available options are:
 .TP
 .B \-h
-Show the version and commandline option help.
+Show the version number and commandline option help, and exit.
 .TP
 .B \-c\fI cfgfile
 Set the config file with settings for unbound to read instead of reading the
@@ -76,6 +76,9 @@
 .B \-v
 Increase verbosity. If given multiple times, more information is logged.
 This is in addition to the verbosity (if any) from the config file.
+.TP
+.B \-V
+Show the version number and build options, and exit.
 .SH "SEE ALSO"
 \fIunbound.conf\fR(5),
 \fIunbound\-checkconf\fR(8),
--- contrib/unbound/doc/unbound.conf.5.orig
+++ contrib/unbound/doc/unbound.conf.5
@@ -1,4 +1,4 @@
-.TH "unbound.conf" "5" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound.conf" "5" "Jun 17, 2019" "NLnet Labs" "unbound 1.9.2"
 .\"
 .\" unbound.conf.5 -- unbound.conf manual
 .\"
@@ -207,6 +207,16 @@
 udp response size maximum, and uses the choice from the client, always.
 Suggested values are 512 to 4096. Default is 4096.
 .TP
+.B stream\-wait\-size: \fI<number>
+Number of bytes size maximum to use for waiting stream buffers.  Default is
+4 megabytes.  A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
+megabytes or gigabytes (1024*1024 bytes in a megabyte).  As TCP and TLS streams
+queue up multiple results, the amount of memory used for these buffers does
+not exceed this number, otherwise the responses are dropped.  This manages
+the total memory usage of the server (under heavy use), the number of requests
+that can be queued up per connection is also limited, with further requests
+waiting in TCP buffers.
+.TP
 .B msg\-buffer\-size: \fI<number>
 Number of bytes size of the message buffers. Default is 65552 bytes, enough
 for 64 Kb packets, the maximum DNS message size. No message larger than this
@@ -253,6 +263,12 @@
 the ID and remote IP of packets, and unwanted packets are added to the
 unwanted packet counter.
 .TP
+.B unknown\-server\-time\-limit: \fI<msec>
+The wait time in msec for waiting for an unknown server to reply.
+Increase this if you are behind a slow satellite link, to eg. 1128.
+That would then avoid re\-querying every initial query because it times out.
+Default is 376 msec.
+.TP
 .B so\-rcvbuf: \fI<number>
 If not 0, then set the SO_RCVBUF socket option to get more buffer
 space on UDP port 53 incoming queries.  So that short spikes on busy
@@ -284,6 +300,8 @@
 it then attempts to open the port and passes the option if it was available
 at compile time, if that works it is used, if it fails, it continues
 silently (unless verbosity 3) without the option.
+At extreme load it could be better to turn it off to distribute the queries
+evenly, reported for Linux systems (4.4.x).
 .TP
 .B ip\-transparent: \fI<yes or no>
 If yes, then use IP_TRANSPARENT socket option on sockets where unbound
@@ -314,11 +332,9 @@
 .TP
 .B cache\-max\-ttl: \fI<seconds>
 Time to live maximum for RRsets and messages in the cache. Default is
-86400 seconds (1 day). If the maximum kicks in, responses to clients
-still get decrementing TTLs based on the original (larger) values.
-When the internal TTL expires, the cache item has expired.
+86400 seconds (1 day).  When the TTL expires, the cache item has expired.
 Can be set lower to force the resolver to query for data often, and not
-trust (very large) TTL values.
+trust (very large) TTL values.  Downstream clients also see the lower TTL.
 .TP
 .B cache\-min\-ttl: \fI<seconds>
 Time to live minimum for RRsets and messages in the cache. Default is 0.
@@ -436,6 +452,8 @@
 \fBtls\-service\-key\fR).
 If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
 load CA certs, otherwise the connections cannot be authenticated.
+This option enables TLS for all of them, but if you do not set this you can
+configure TLS specifically for some forward zones with forward\-tls\-upstream.  And also with stub\-tls\-upstream.
 .TP
 .B ssl\-upstream: \fI<yes or no>
 Alternate syntax for \fBtls\-upstream\fR.  If both are present in the config
@@ -442,14 +460,15 @@
 file the last is used.
 .TP
 .B tls\-service\-key: \fI<file>
-If enabled, the server provider TLS service on its TCP sockets.  The clients
-have to use tls\-upstream: yes.  The file is the private key for the TLS
-session.  The public certificate is in the tls\-service\-pem file.  Default
-is "", turned off.  Requires a restart (a reload is not enough) if changed,
-because the private key is read while root permissions are held and before
-chroot (if any).  Normal DNS TCP service is not provided and gives errors,
-this service is best run with a different \fBport:\fR config or \fI@port\fR
-suffixes in the \fBinterface\fR config.
+If enabled, the server provides TLS service on the TCP ports marked
+implicitly or explicitly for TLS service with tls\-port.  The file must
+contain the private key for the TLS session, the public certificate is in
+the tls\-service\-pem file and it must also be specified if tls\-service\-key
+is specified.  The default is "", turned off.  Enabling or disabling
+this service requires a restart (a reload is not enough), because the
+key is read while root permissions are held and before chroot (if any).
+The ports enabled implicitly or explicitly via \fBtls\-port:\fR do not provide
+normal DNS TCP service.
 .TP
 .B ssl\-service\-key: \fI<file>
 Alternate syntax for \fBtls\-service\-key\fR.
@@ -488,6 +507,27 @@
 eg. with the @port suffix, as this port number, they provide dns over TLS
 service.  Can list multiple, each on a new statement.
 .TP
+.B tls-session-ticket-keys: \fI<file>
+If not "", lists files with 80 bytes of random contents that are used to
+perform TLS session resumption for clients using the unbound server.
+These files contain the secret key for the TLS session tickets.
+First key use to encrypt and decrypt TLS session tickets.
+Other keys use to decrypt only.  With this you can roll over to new keys,
+by generating a new first file and allowing decrypt of the old file by
+listing it after the first file for some time, after the wait clients are not
+using the old key any more and the old key can be removed.
+One way to create the file is dd if=/dev/random bs=1 count=80 of=ticket.dat
+The first 16 bytes should be different from the old one if you create a second key, that is the name used to identify the key.  Then there is 32 bytes random
+data for an AES key and then 32 bytes random data for the HMAC key.
+.TP
+.B tls\-ciphers: \fI<string with cipher list>
+Set the list of ciphers to allow when serving TLS.  Use "" for defaults,
+and that is the default.
+.TP
+.B tls\-ciphersuites: \fI<string with ciphersuites list>
+Set the list of ciphersuites to allow when serving TLS.  This is for newer
+TLS 1.3 connections.  Use "" for defaults, and that is the default.
+.TP
 .B use\-systemd: \fI<yes or no>
 Enable or disable systemd socket activation.
 Default is no.
@@ -508,6 +548,7 @@
 \fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
 \fIrefuse_non_local\fR.
 The most specific netblock match is used, if none match \fIdeny\fR is used.
+The order of the access\-control statements therefore does not matter.
 .IP
 The action \fIdeny\fR stops queries from hosts from that netblock.
 .IP
@@ -655,6 +696,11 @@
 lines which makes the server (significantly) slower.  Odd (nonprintable)
 characters in names are printed as '?'.
 .TP
+.B log\-tag\-queryreply: \fI<yes or no>
+Prints the word 'query' and 'reply' with log\-queries and log\-replies.
+This makes filtering logs easier.  The default is off (for backwards
+compatibility).
+.TP
 .B log\-local\-actions: \fI<yes or no>
 Print log lines to inform about local zone actions.  These lines are like the
 local\-zone type inform prints out, but they are also printed for the other
@@ -784,7 +830,7 @@
 .TP
 .B qname\-minimisation: \fI<yes or no>
 Send minimum amount of information to upstream servers to enhance privacy.
-Only sent minimum required labels of the QNAME and set QTYPE to A when
+Only send minimum required labels of the QNAME and set QTYPE to A when
 possible. Best effort approach; full QNAME and original QTYPE will be sent when
 upstream replies with a RCODE other than NOERROR, except when receiving
 NXDOMAIN from a DNSSEC signed zone. Default is yes.
@@ -848,12 +894,18 @@
 10 percent more traffic and load on the machine, but popular items do
 not expire from the cache.
 .TP
-.B prefetch-key: \fI<yes or no>
+.B prefetch\-key: \fI<yes or no>
 If yes, fetch the DNSKEYs earlier in the validation process, when a DS
 record is encountered.  This lowers the latency of requests.  It does use
 a little more CPU.  Also if the cache is set to 0, it is no use. Default is no.
 .TP
-.B rrset-roundrobin: \fI<yes or no>
+.B deny\-any: \fI<yes or no>
+If yes, deny queries of type ANY with an empty response.  Default is no.
+If disabled, unbound responds with a short list of resource records if some
+can be found in the cache and makes the upstream type ANY query if there
+are none.
+.TP
+.B rrset\-roundrobin: \fI<yes or no>
 If yes, Unbound rotates RRSet order in response (the random number is taken
 from the query ID, for speed and thread safety).  Default is no.
 .TP
@@ -881,6 +933,12 @@
 Setting this to "validator iterator" will turn on DNSSEC validation.
 The ordering of the modules is important.
 You must also set trust\-anchors for validation to be useful.
+The default is "validator iterator".  When the server is built with
+EDNS client subnet support the default is "subnetcache validator iterator".
+Most modules that need to be listed here have to be listed at the beginning
+of the line.  The cachedb module has to be listed just before the iterator.
+The python module can be listed in different places, it then processes the
+output of the module it is just before.
 .TP
 .B trust\-anchor\-file: \fI<filename>
 File with trusted keys for validation. Both DS and DNSKEY entries can appear
@@ -1092,7 +1150,7 @@
 Configure a local zone. The type determines the answer to give if
 there is no match from local\-data. The types are deny, refuse, static,
 transparent, redirect, nodefault, typetransparent, inform, inform_deny,
-always_transparent, always_refuse, always_nxdomain, noview,
+inform_redirect, always_transparent, always_refuse, always_nxdomain, noview,
 and are explained below. After that the default settings are listed. Use
 local\-data: to enter data into the local zone. Answers for local zones
 are authoritative DNS answers. By default the zones are class IN.
@@ -1153,6 +1211,10 @@
 The query is dropped, like 'deny', and logged, like 'inform'.  Ie. find
 infected machines without answering the queries.
 .TP 10
+\h'5'\fIinform_redirect\fR
+The query is redirected, like 'redirect', and logged, like 'inform'.
+Ie. answer queries with fixed data and also log the machines that ask.
+.TP 10
 \h'5'\fIalways_transparent\fR
 Like transparent, but ignores local data and resolves normally.
 .TP 10
@@ -1308,7 +1370,8 @@
 Assign tags to localzones. Tagged localzones will only be applied when the
 used access-control element has a matching tag. Tags must be defined in
 \fIdefine\-tags\fR.  Enclose list of tags in quotes ("") and put spaces between
-tags.
+tags.  When there are multiple tags it checks if the intersection of the
+list of tags for the query and local\-zone\-tag is non-empty.
 .TP 5
 .B local\-zone\-override: \fI<zone> <IP netblock> <type>
 Override the localzone type for queries from addresses matching netblock.
@@ -1391,22 +1454,20 @@
 and enter the cache, whilst also mitigating the traffic flow by the
 factor given.
 .TP 5
-.B low\-rtt: \fI<msec time>
-Set the time in millisecond that is considere a low ping time for fast
-server selection with the low\-rtt\-permil option, that turns this on or off.
-The default is 45 msec, a number from IPv6 quick response documents.
+.B fast\-server\-permil: \fI<number>
+Specify how many times out of 1000 to pick from the set of fastest servers.
+0 turns the feature off.  A value of 900 would pick from the fastest
+servers 90 percent of the time, and would perform normal exploration of random
+servers for the remaining time. When prefetch is enabled (or serve\-expired),
+such prefetches are not sped up, because there is no one waiting for it, and it
+presents a good moment to perform server exploration. The
+\fBfast\-server\-num\fR option can be used to specify the size of the fastest
+servers set. The default for fast\-server\-permil is 0.
 .TP 5
-.B low\-rtt\-permil: \fI<number>
-Specify how many times out of 1000 to pick the fast server from the low
-rtt band.  0 turns the feature off.  A value of 900 would pick the fast
-server when such fast servers are available 90 percent of the time, and
-the remaining time perform normal exploration of random servers.
-When prefetch is enabled (or serve\-expired), such prefetches are not
-sped up, because there is no one waiting for it, and it presents a good
-moment to perform server exploration.  The low\-rtt option can be used
-to specify which servers are picked for fast server selection, servers
-with a ping roundtrip time below that value are considered.
-The default for low\-rtt\-permil is 0.
+.B fast\-server\-num: \fI<number>
+Set the number of servers that should be used for fast server selection. Only
+use the fastest specified number of servers with the fast\-server\-permil
+option, that turns this on or off. The default is to use the fastest 3 servers.
 .SS "Remote Control Options"
 In the
 .B remote\-control:
@@ -1568,13 +1629,11 @@
 At high verbosity it logs the TLS certificate, with TLS enabled.
 If you leave out the '#' and auth name from the forward\-addr, any
 name is accepted.  The cert must also match a CA from the tls\-cert\-bundle.
-The cert name match code needs OpenSSL 1.1.0 or later to be enabled.
 .TP
 .B forward\-first: \fI<yes or no>
-If enabled, a query is attempted without the forward clause if it fails.
-The data could not be retrieved and would have caused SERVFAIL because
-the servers are unreachable, instead it is tried without this clause.
-The default is no.
+If a forwarded query is met with a SERVFAIL error, and this option is
+enabled, unbound will fall back to normal recursive resolution for this
+query as if no query forwarding had been specified.  The default is "no".
 .TP
 .B forward\-tls\-upstream: \fI<yes or no>
 Enabled or disable whether the queries to this forwarder use TLS for transport.
@@ -1604,6 +1663,13 @@
 Authority zones can be read from zonefile.  And can be kept updated via
 AXFR and IXFR.  After update the zonefile is rewritten.  The update mechanism
 uses the SOA timer values and performs SOA UDP queries to detect zone changes.
+.LP
+If the update fetch fails, the timers in the SOA record are used to time
+another fetch attempt.  Until the SOA expiry timer is reached.  Then the
+zone is expired.  When a zone is expired, queries are SERVFAIL, and
+any new serial number is accepted from the master (even if older), and if
+fallback is enabled, the fallback activates to fetch from the upstream instead
+of the SERVFAIL.
 .TP
 .B name: \fI<zone name>
 Name of the authority zone.
@@ -1611,6 +1677,7 @@
 .B master: \fI<IP address or host name>
 Where to download a copy of the zone from, with AXFR and IXFR.  Multiple
 masters can be specified.  They are all tried if one fails.
+With the "ip#name" notation a AXFR over TLS can be used.
 .TP
 .B url: \fI<url to zonefile>
 Where to download a zonefile for the zone.  With http or https.  An example
@@ -1662,7 +1729,9 @@
 There may be multiple
 .B view:
 clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
-\fBlocal\-data\fR elements. View can be mapped to requests by specifying the
+\fBlocal\-data\fR elements. Views can also contain view\-first, 
+response\-ip, response\-ip\-data and local\-data\-ptr elements.
+View can be mapped to requests by specifying the
 view name in an \fBaccess\-control\-view\fR element. Options from matching
 views will override global options. Global options will be used if no matching
 view is found, or when the matching view does not have the option specified.
@@ -1843,6 +1912,24 @@
 .B max\-client\-subnet\-ipv4: \fI<number>\fR
 Specifies the maximum prefix length of the client source address we are willing
 to expose to third parties for IPv4. Defaults to 24.
+.TP
+.B min\-client\-subnet\-ipv6: \fI<number>\fR
+Specifies the minimum prefix length of the IPv6 source mask we are willing to
+accept in queries. Shorter source masks result in REFUSED answers. Source mask
+of 0 is always accepted. Default is 0.
+.TP
+.B min\-client\-subnet\-ipv4: \fI<number>\fR
+Specifies the minimum prefix length of the IPv4 source mask we are willing to
+accept in queries. Shorter source masks result in REFUSED answers. Source mask 
+of 0 is always accepted. Default is 0.
+.TP
+.B max\-ecs\-tree\-size\-ipv4: \fI<number>\fR
+Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
+This number applies for each qname/qclass/qtype tuple. Defaults to 100.
+.TP
+.B max\-ecs\-tree\-size\-ipv6: \fI<number>\fR
+Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
+This number applies for each qname/qclass/qtype tuple. Defaults to 100.
 .SS "Opportunistic IPsec Support Module Options"
 .LP
 The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod
--- contrib/unbound/doc/unbound.conf.5.in.orig
+++ contrib/unbound/doc/unbound.conf.5.in
@@ -1,4 +1,4 @@
-.TH "unbound.conf" "5" "Oct  8, 2018" "NLnet Labs" "unbound 1.8.1"
+.TH "unbound.conf" "5" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
 .\"
 .\" unbound.conf.5 -- unbound.conf manual
 .\"
@@ -50,7 +50,7 @@
 	username: unbound
 	# make sure unbound can access entropy from inside the chroot.
 	# e.g. on linux the use these commands (on BSD, devfs(8) is used):
-	#      mount \-\-bind \-n /dev/random /etc/unbound/dev/random
+	#      mount \-\-bind \-n /dev/urandom /etc/unbound/dev/urandom
 	# and  mount \-\-bind \-n /dev/log /etc/unbound/dev/log
 	chroot: "/etc/unbound"
 	# logfile: "/etc/unbound/unbound.log"  #uncomment to use logfile.
@@ -63,8 +63,10 @@
 	access\-control: 2001:DB8::/64 allow
 .fi
 .SH "FILE FORMAT"
-There must be whitespace between keywords. Attribute keywords end with a colon ':'.
-An attribute is followed by its containing attributes, or a value.
+There must be whitespace between keywords.  Attribute keywords end with a
+colon ':'.  An attribute is followed by a value, or its containing attributes
+in which case it is referred to as a clause.  Clauses can be repeated throughout
+the file (or included files) to group attributes under the same clause.
 .P
 Files can be included using the
 .B include:
@@ -207,6 +209,16 @@
 udp response size maximum, and uses the choice from the client, always.
 Suggested values are 512 to 4096. Default is 4096.
 .TP
+.B stream\-wait\-size: \fI<number>
+Number of bytes size maximum to use for waiting stream buffers.  Default is
+4 megabytes.  A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
+megabytes or gigabytes (1024*1024 bytes in a megabyte).  As TCP and TLS streams
+queue up multiple results, the amount of memory used for these buffers does
+not exceed this number, otherwise the responses are dropped.  This manages
+the total memory usage of the server (under heavy use), the number of requests
+that can be queued up per connection is also limited, with further requests
+waiting in TCP buffers.
+.TP
 .B msg\-buffer\-size: \fI<number>
 Number of bytes size of the message buffers. Default is 65552 bytes, enough
 for 64 Kb packets, the maximum DNS message size. No message larger than this
@@ -253,6 +265,12 @@
 the ID and remote IP of packets, and unwanted packets are added to the
 unwanted packet counter.
 .TP
+.B unknown\-server\-time\-limit: \fI<msec>
+The wait time in msec for waiting for an unknown server to reply.
+Increase this if you are behind a slow satellite link, to eg. 1128.
+That would then avoid re\-querying every initial query because it times out.
+Default is 376 msec.
+.TP
 .B so\-rcvbuf: \fI<number>
 If not 0, then set the SO_RCVBUF socket option to get more buffer
 space on UDP port 53 incoming queries.  So that short spikes on busy
@@ -284,6 +302,8 @@
 it then attempts to open the port and passes the option if it was available
 at compile time, if that works it is used, if it fails, it continues
 silently (unless verbosity 3) without the option.
+At extreme load it could be better to turn it off to distribute the queries
+evenly, reported for Linux systems (4.4.x).
 .TP
 .B ip\-transparent: \fI<yes or no>
 If yes, then use IP_TRANSPARENT socket option on sockets where unbound
@@ -314,11 +334,9 @@
 .TP
 .B cache\-max\-ttl: \fI<seconds>
 Time to live maximum for RRsets and messages in the cache. Default is
-86400 seconds (1 day). If the maximum kicks in, responses to clients
-still get decrementing TTLs based on the original (larger) values.
-When the internal TTL expires, the cache item has expired.
+86400 seconds (1 day).  When the TTL expires, the cache item has expired.
 Can be set lower to force the resolver to query for data often, and not
-trust (very large) TTL values.
+trust (very large) TTL values.  Downstream clients also see the lower TTL.
 .TP
 .B cache\-min\-ttl: \fI<seconds>
 Time to live minimum for RRsets and messages in the cache. Default is 0.
@@ -436,6 +454,8 @@
 \fBtls\-service\-key\fR).
 If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
 load CA certs, otherwise the connections cannot be authenticated.
+This option enables TLS for all of them, but if you do not set this you can
+configure TLS specifically for some forward zones with forward\-tls\-upstream.  And also with stub\-tls\-upstream.
 .TP
 .B ssl\-upstream: \fI<yes or no>
 Alternate syntax for \fBtls\-upstream\fR.  If both are present in the config
@@ -442,14 +462,15 @@
 file the last is used.
 .TP
 .B tls\-service\-key: \fI<file>
-If enabled, the server provider TLS service on its TCP sockets.  The clients
-have to use tls\-upstream: yes.  The file is the private key for the TLS
-session.  The public certificate is in the tls\-service\-pem file.  Default
-is "", turned off.  Requires a restart (a reload is not enough) if changed,
-because the private key is read while root permissions are held and before
-chroot (if any).  Normal DNS TCP service is not provided and gives errors,
-this service is best run with a different \fBport:\fR config or \fI@port\fR
-suffixes in the \fBinterface\fR config.
+If enabled, the server provides TLS service on the TCP ports marked
+implicitly or explicitly for TLS service with tls\-port.  The file must
+contain the private key for the TLS session, the public certificate is in
+the tls\-service\-pem file and it must also be specified if tls\-service\-key
+is specified.  The default is "", turned off.  Enabling or disabling
+this service requires a restart (a reload is not enough), because the
+key is read while root permissions are held and before chroot (if any).
+The ports enabled implicitly or explicitly via \fBtls\-port:\fR do not provide
+normal DNS TCP service.
 .TP
 .B ssl\-service\-key: \fI<file>
 Alternate syntax for \fBtls\-service\-key\fR.
@@ -488,6 +509,27 @@
 eg. with the @port suffix, as this port number, they provide dns over TLS
 service.  Can list multiple, each on a new statement.
 .TP
+.B tls-session-ticket-keys: \fI<file>
+If not "", lists files with 80 bytes of random contents that are used to
+perform TLS session resumption for clients using the unbound server.
+These files contain the secret key for the TLS session tickets.
+First key use to encrypt and decrypt TLS session tickets.
+Other keys use to decrypt only.  With this you can roll over to new keys,
+by generating a new first file and allowing decrypt of the old file by
+listing it after the first file for some time, after the wait clients are not
+using the old key any more and the old key can be removed.
+One way to create the file is dd if=/dev/random bs=1 count=80 of=ticket.dat
+The first 16 bytes should be different from the old one if you create a second key, that is the name used to identify the key.  Then there is 32 bytes random
+data for an AES key and then 32 bytes random data for the HMAC key.
+.TP
+.B tls\-ciphers: \fI<string with cipher list>
+Set the list of ciphers to allow when serving TLS.  Use "" for defaults,
+and that is the default.
+.TP
+.B tls\-ciphersuites: \fI<string with ciphersuites list>
+Set the list of ciphersuites to allow when serving TLS.  This is for newer
+TLS 1.3 connections.  Use "" for defaults, and that is the default.
+.TP
 .B use\-systemd: \fI<yes or no>
 Enable or disable systemd socket activation.
 Default is no.
@@ -508,6 +550,7 @@
 \fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
 \fIrefuse_non_local\fR.
 The most specific netblock match is used, if none match \fIdeny\fR is used.
+The order of the access\-control statements therefore does not matter.
 .IP
 The action \fIdeny\fR stops queries from hosts from that netblock.
 .IP
@@ -588,9 +631,11 @@
 The pidfile can be either a relative path to the working directory, or
 an absolute path relative to the original root. It is written just prior
 to chroot and dropping permissions. This allows the pidfile to be
-/var/run/unbound.pid and the chroot to be /var/unbound, for example.
+/var/run/unbound.pid and the chroot to be /var/unbound, for example. Note that
+Unbound is not able to remove the pidfile after termination when it is located
+outside of the chroot directory.
 .IP
-Additionally, unbound may need to access /dev/random (for entropy)
+Additionally, unbound may need to access /dev/urandom (for entropy)
 from inside the chroot.
 .IP
 If given a chroot is done to the given directory. By default chroot is
@@ -655,6 +700,11 @@
 lines which makes the server (significantly) slower.  Odd (nonprintable)
 characters in names are printed as '?'.
 .TP
+.B log\-tag\-queryreply: \fI<yes or no>
+Prints the word 'query' and 'reply' with log\-queries and log\-replies.
+This makes filtering logs easier.  The default is off (for backwards
+compatibility).
+.TP
 .B log\-local\-actions: \fI<yes or no>
 Print log lines to inform about local zone actions.  These lines are like the
 local\-zone type inform prints out, but they are also printed for the other
@@ -727,7 +777,7 @@
 payload is very large.
 .TP
 .B harden\-glue: \fI<yes or no>
-Will trust glue only if it is within the servers authority. Default is on.
+Will trust glue only if it is within the servers authority. Default is yes.
 .TP
 .B harden\-dnssec\-stripped: \fI<yes or no>
 Require DNSSEC data for trust\-anchored zones, if such data is absent,
@@ -737,7 +787,7 @@
 you are sometimes behind an intrusive firewall (of some sort) that
 removes DNSSEC data from packets, or a zone changes from signed to
 unsigned to badly signed often. If turned off you run the risk of a
-downgrade attack that disables security for a zone. Default is on.
+downgrade attack that disables security for a zone. Default is yes.
 .TP
 .B harden\-below\-nxdomain: \fI<yes or no>
 From RFC 8020 (with title "NXDOMAIN: There Really Is Nothing Underneath"),
@@ -747,7 +797,7 @@
 might return nxdomain for empty nonterminals (that usually happen for reverse
 IP address lookups), and thus may be incompatible with this.  To try to avoid
 this only DNSSEC-secure nxdomains are used, because the old software does not
-have DNSSEC.  Default is on.
+have DNSSEC.  Default is yes.
 The nxdomain must be secure, this means nsec3 with optout is insufficient.
 .TP
 .B harden\-referral\-path: \fI<yes or no>
@@ -784,7 +834,7 @@
 .TP
 .B qname\-minimisation: \fI<yes or no>
 Send minimum amount of information to upstream servers to enhance privacy.
-Only sent minimum required labels of the QNAME and set QTYPE to A when
+Only send minimum required labels of the QNAME and set QTYPE to A when
 possible. Best effort approach; full QNAME and original QTYPE will be sent when
 upstream replies with a RCODE other than NOERROR, except when receiving
 NXDOMAIN from a DNSSEC signed zone. Default is yes.
@@ -848,12 +898,18 @@
 10 percent more traffic and load on the machine, but popular items do
 not expire from the cache.
 .TP
-.B prefetch-key: \fI<yes or no>
+.B prefetch\-key: \fI<yes or no>
 If yes, fetch the DNSKEYs earlier in the validation process, when a DS
 record is encountered.  This lowers the latency of requests.  It does use
 a little more CPU.  Also if the cache is set to 0, it is no use. Default is no.
 .TP
-.B rrset-roundrobin: \fI<yes or no>
+.B deny\-any: \fI<yes or no>
+If yes, deny queries of type ANY with an empty response.  Default is no.
+If disabled, unbound responds with a short list of resource records if some
+can be found in the cache and makes the upstream type ANY query if there
+are none.
+.TP
+.B rrset\-roundrobin: \fI<yes or no>
 If yes, Unbound rotates RRSet order in response (the random number is taken
 from the query ID, for speed and thread safety).  Default is no.
 .TP
@@ -881,6 +937,12 @@
 Setting this to "validator iterator" will turn on DNSSEC validation.
 The ordering of the modules is important.
 You must also set trust\-anchors for validation to be useful.
+The default is "validator iterator".  When the server is built with
+EDNS client subnet support the default is "subnetcache validator iterator".
+Most modules that need to be listed here have to be listed at the beginning
+of the line.  The cachedb module has to be listed just before the iterator.
+The python module can be listed in different places, it then processes the
+output of the module it is just before.
 .TP
 .B trust\-anchor\-file: \fI<filename>
 File with trusted keys for validation. Both DS and DNSKEY entries can appear
@@ -889,7 +951,7 @@
 .TP
 .B auto\-trust\-anchor\-file: \fI<filename>
 File with trust anchor for one zone, which is tracked with RFC5011 probes.
-The probes are several times per month, thus the machine must be online
+The probes are run several times per month, thus the machine must be online
 frequently.  The initial file can be one with contents as described in
 \fBtrust\-anchor\-file\fR.  The file is written to when the anchor is updated,
 so the unbound user must have write permission.  Write permission to the file,
@@ -914,10 +976,10 @@
 expanded on start and on reload.
 .TP
 .B trust\-anchor\-signaling: \fI<yes or no>
-Send RFC8145 key tag query after trust anchor priming. Default is on.
+Send RFC8145 key tag query after trust anchor priming. Default is yes.
 .TP
 .B root\-key\-sentinel: \fI<yes or no>
-Root key trust anchor sentinel. Default is on.
+Root key trust anchor sentinel. Default is yes.
 .TP
 .B dlv\-anchor\-file: \fI<filename>
 This option was used during early days DNSSEC deployment when no parent-side
@@ -1010,20 +1072,35 @@
 .TP
 .B serve\-expired: \fI<yes or no>
 If enabled, unbound attempts to serve old responses from cache with a
-TTL of 0 in the response without waiting for the actual resolution to finish.
-The actual resolution answer ends up in the cache later on.  Default is "no".
+TTL of \fBserve\-expired\-reply\-ttl\fR in the response without waiting for the
+actual resolution to finish.  The actual resolution answer ends up in the cache
+later on.  Default is "no".
 .TP
 .B serve\-expired\-ttl: \fI<seconds>
 Limit serving of expired responses to configured seconds after expiration. 0
-disables the limit. This option only applies when \fBserve\-expired\fR is
-enabled. The default is 0.
+disables the limit.  This option only applies when \fBserve\-expired\fR is
+enabled.  A suggested value per draft-ietf-dnsop-serve-stale-10 is between
+86400 (1 day) and 259200 (3 days).  The default is 0.
 .TP
 .B serve\-expired\-ttl\-reset: \fI<yes or no>
 Set the TTL of expired records to the \fBserve\-expired\-ttl\fR value after a
-failed attempt to retrieve the record from upstream. This makes sure that the
-expired records will be served as long as there are queries for it. Default is
+failed attempt to retrieve the record from upstream.  This makes sure that the
+expired records will be served as long as there are queries for it.  Default is
 "no".
 .TP
+.B serve\-expired\-reply\-ttl: \fI<seconds>
+TTL value to use when replying with expired data.  If
+\fBserve\-expired\-client\-timeout\fR is also used then it is RECOMMENDED to
+use 30 as the value (draft-ietf-dnsop-serve-stale-10).  The default is 30.
+.TP
+.B serve\-expired\-client\-timeout: \fI<msec>
+Time in milliseconds before replying to the client with expired data.  This
+essentially enables the serve-stale behavior as specified in
+draft-ietf-dnsop-serve-stale-10 that first tries to resolve before immediately
+responding with expired data.  A recommended value per
+draft-ietf-dnsop-serve-stale-10 is 1800.  Setting this to 0 will disable this
+behavior.  Default is 0.
+.TP
 .B val\-nsec3\-keysize\-iterations: \fI<"list of values">
 List of keysize and iteration count values, separated by spaces, surrounded
 by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
@@ -1092,7 +1169,7 @@
 Configure a local zone. The type determines the answer to give if
 there is no match from local\-data. The types are deny, refuse, static,
 transparent, redirect, nodefault, typetransparent, inform, inform_deny,
-always_transparent, always_refuse, always_nxdomain, noview,
+inform_redirect, always_transparent, always_refuse, always_nxdomain, noview,
 and are explained below. After that the default settings are listed. Use
 local\-data: to enter data into the local zone. Answers for local zones
 are authoritative DNS answers. By default the zones are class IN.
@@ -1153,6 +1230,10 @@
 The query is dropped, like 'deny', and logged, like 'inform'.  Ie. find
 infected machines without answering the queries.
 .TP 10
+\h'5'\fIinform_redirect\fR
+The query is redirected, like 'redirect', and logged, like 'inform'.
+Ie. answer queries with fixed data and also log the machines that ask.
+.TP 10
 \h'5'\fIalways_transparent\fR
 Like transparent, but ignores local data and resolves normally.
 .TP 10
@@ -1232,7 +1313,7 @@
     SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
 .fi
 .TP 10
-\h'5'\fItest (RFC 2606)\fR
+\h'5'\fItest (RFC 6761)\fR
 Default content:
 .nf
 local\-zone: "test." static
@@ -1241,7 +1322,7 @@
     SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
 .fi
 .TP 10
-\h'5'\fIinvalid (RFC 2606)\fR
+\h'5'\fIinvalid (RFC 6761)\fR
 Default content:
 .nf
 local\-zone: "invalid." static
@@ -1308,7 +1389,8 @@
 Assign tags to localzones. Tagged localzones will only be applied when the
 used access-control element has a matching tag. Tags must be defined in
 \fIdefine\-tags\fR.  Enclose list of tags in quotes ("") and put spaces between
-tags.
+tags.  When there are multiple tags it checks if the intersection of the
+list of tags for the query and local\-zone\-tag is non-empty.
 .TP 5
 .B local\-zone\-override: \fI<zone> <IP netblock> <type>
 Override the localzone type for queries from addresses matching netblock.
@@ -1391,22 +1473,20 @@
 and enter the cache, whilst also mitigating the traffic flow by the
 factor given.
 .TP 5
-.B low\-rtt: \fI<msec time>
-Set the time in millisecond that is considere a low ping time for fast
-server selection with the low\-rtt\-permil option, that turns this on or off.
-The default is 45 msec, a number from IPv6 quick response documents.
+.B fast\-server\-permil: \fI<number>
+Specify how many times out of 1000 to pick from the set of fastest servers.
+0 turns the feature off.  A value of 900 would pick from the fastest
+servers 90 percent of the time, and would perform normal exploration of random
+servers for the remaining time. When prefetch is enabled (or serve\-expired),
+such prefetches are not sped up, because there is no one waiting for it, and it
+presents a good moment to perform server exploration. The
+\fBfast\-server\-num\fR option can be used to specify the size of the fastest
+servers set. The default for fast\-server\-permil is 0.
 .TP 5
-.B low\-rtt\-permil: \fI<number>
-Specify how many times out of 1000 to pick the fast server from the low
-rtt band.  0 turns the feature off.  A value of 900 would pick the fast
-server when such fast servers are available 90 percent of the time, and
-the remaining time perform normal exploration of random servers.
-When prefetch is enabled (or serve\-expired), such prefetches are not
-sped up, because there is no one waiting for it, and it presents a good
-moment to perform server exploration.  The low\-rtt option can be used
-to specify which servers are picked for fast server selection, servers
-with a ping roundtrip time below that value are considered.
-The default for low\-rtt\-permil is 0.
+.B fast\-server\-num: \fI<number>
+Set the number of servers that should be used for fast server selection. Only
+use the fastest specified number of servers with the fast\-server\-permil
+option, that turns this on or off. The default is to use the fastest 3 servers.
 .SS "Remote Control Options"
 In the
 .B remote\-control:
@@ -1568,13 +1648,11 @@
 At high verbosity it logs the TLS certificate, with TLS enabled.
 If you leave out the '#' and auth name from the forward\-addr, any
 name is accepted.  The cert must also match a CA from the tls\-cert\-bundle.
-The cert name match code needs OpenSSL 1.1.0 or later to be enabled.
 .TP
 .B forward\-first: \fI<yes or no>
-If enabled, a query is attempted without the forward clause if it fails.
-The data could not be retrieved and would have caused SERVFAIL because
-the servers are unreachable, instead it is tried without this clause.
-The default is no.
+If a forwarded query is met with a SERVFAIL error, and this option is
+enabled, unbound will fall back to normal recursive resolution for this
+query as if no query forwarding had been specified.  The default is "no".
 .TP
 .B forward\-tls\-upstream: \fI<yes or no>
 Enabled or disable whether the queries to this forwarder use TLS for transport.
@@ -1604,6 +1682,13 @@
 Authority zones can be read from zonefile.  And can be kept updated via
 AXFR and IXFR.  After update the zonefile is rewritten.  The update mechanism
 uses the SOA timer values and performs SOA UDP queries to detect zone changes.
+.LP
+If the update fetch fails, the timers in the SOA record are used to time
+another fetch attempt.  Until the SOA expiry timer is reached.  Then the
+zone is expired.  When a zone is expired, queries are SERVFAIL, and
+any new serial number is accepted from the master (even if older), and if
+fallback is enabled, the fallback activates to fetch from the upstream instead
+of the SERVFAIL.
 .TP
 .B name: \fI<zone name>
 Name of the authority zone.
@@ -1611,6 +1696,13 @@
 .B master: \fI<IP address or host name>
 Where to download a copy of the zone from, with AXFR and IXFR.  Multiple
 masters can be specified.  They are all tried if one fails.
+With the "ip#name" notation a AXFR over TLS can be used.
+If you point it at another Unbound instance, it would not work because
+that does not support AXFR/IXFR for the zone, but if you used \fBurl:\fR to download
+the zonefile as a text file from a webserver that would work.
+If you specify the hostname, you cannot use the domain from the zonefile,
+because it may not have that when retrieving that data, instead use a plain
+IP address to avoid a circular dependency on retrieving that IP address.
 .TP
 .B url: \fI<url to zonefile>
 Where to download a zonefile for the zone.  With http or https.  An example
@@ -1622,6 +1714,10 @@
 If none of the urls work, the masters are tried with IXFR and AXFR.
 For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
 to authenticate the connection.
+If you specify a hostname in the URL, you cannot use the domain from the
+zonefile, because it may not have that when retrieving that data, instead
+use a plain IP address to avoid a circular dependency on retrieving that IP
+address.  Avoid dependencies on name lookups by using a notation like "http://192.0.2.1/unbound-master/example.com.zone", with an explicit IP address.
 .TP
 .B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
 With allow\-notify you can specify additional sources of notifies.
@@ -1662,7 +1758,9 @@
 There may be multiple
 .B view:
 clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
-\fBlocal\-data\fR elements. View can be mapped to requests by specifying the
+\fBlocal\-data\fR elements. Views can also contain view\-first, 
+response\-ip, response\-ip\-data and local\-data\-ptr elements.
+View can be mapped to requests by specifying the
 view name in an \fBaccess\-control\-view\fR element. Options from matching
 views will override global options. Global options will be used if no matching
 view is found, or when the matching view does not have the option specified.
@@ -1699,7 +1797,8 @@
 acts like the iterator and validator modules do, on queries and answers.
 To enable the script module it has to be compiled into the daemon,
 and the word "python" has to be put in the \fBmodule\-config:\fR option
-(usually first, or between the validator and iterator).
+(usually first, or between the validator and iterator). Multiple instances of
+the python module are supported by adding the word "python" more than once.
 .LP
 If the \fBchroot:\fR option is enabled, you should make sure Python's
 library directory structure is bind mounted in the new root environment, see
@@ -1708,7 +1807,8 @@
 directory.
 .TP
 .B python\-script: \fI<python file>\fR
-The script file to load.
+The script file to load. Repeat this option for every python module instance
+added to the \fBmodule\-config:\fR option.
 .SS "DNS64 Module Options"
 .LP
 The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
@@ -1843,6 +1943,24 @@
 .B max\-client\-subnet\-ipv4: \fI<number>\fR
 Specifies the maximum prefix length of the client source address we are willing
 to expose to third parties for IPv4. Defaults to 24.
+.TP
+.B min\-client\-subnet\-ipv6: \fI<number>\fR
+Specifies the minimum prefix length of the IPv6 source mask we are willing to
+accept in queries. Shorter source masks result in REFUSED answers. Source mask
+of 0 is always accepted. Default is 0.
+.TP
+.B min\-client\-subnet\-ipv4: \fI<number>\fR
+Specifies the minimum prefix length of the IPv4 source mask we are willing to
+accept in queries. Shorter source masks result in REFUSED answers. Source mask 
+of 0 is always accepted. Default is 0.
+.TP
+.B max\-ecs\-tree\-size\-ipv4: \fI<number>\fR
+Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
+This number applies for each qname/qclass/qtype tuple. Defaults to 100.
+.TP
+.B max\-ecs\-tree\-size\-ipv6: \fI<number>\fR
+Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
+This number applies for each qname/qclass/qtype tuple. Defaults to 100.
 .SS "Opportunistic IPsec Support Module Options"
 .LP
 The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod
@@ -1923,6 +2041,13 @@
 If Unbound cannot even find an answer in the backend, it resolves the
 query as usual, and stores the answer in the backend.
 .P
+This module interacts with the \fBserve\-expired\-*\fR options and will reply
+with expired data if unbound is configured for that.  Currently the use
+of \fBserve\-expired\-client\-timeout:\fR and
+\fBserve\-expired\-reply\-ttl:\fR is not consistent for data originating from
+the external cache as these will result in a reply with 0 TTL without trying to
+update the data first, ignoring the configured values.
+.P
 If Unbound was built with
 \fB\-\-with\-libhiredis\fR
 on a system that has installed the hiredis C client library of Redis,
@@ -1989,6 +2114,70 @@
 if the Redis server does not have the requested data, and will try to
 re-establish a new connection later.
 This option defaults to 100 milliseconds.
+.SS Response Policy Zone Options
+.LP
+Response Policy Zones are configured with \fBrpz:\fR, and each one must have a
+\fBname:\fR. There can be multiple ones, by listing multiple rpz clauses, each
+with a different name. RPZ clauses are applied in order of configuration. The
+\fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
+\fBmodule-config: "respip validator iterator"\fR.
+.P
+Only the QNAME and Response IP Address triggers are supported. The supported RPZ
+actions are: NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. RPZ QNAME triggers
+are applied after
+\fBlocal-zones\fR and before \fBauth-zones\fR.
+.TP
+.B name: \fI<zone name>
+Name of the authority zone.
+.TP
+.B master: \fI<IP address or host name>
+Where to download a copy of the zone from, with AXFR and IXFR.  Multiple
+masters can be specified.  They are all tried if one fails.
+.TP
+.B url: \fI<url to zonefile>
+Where to download a zonefile for the zone.  With http or https.  An example
+for the url is "http://www.example.com/example.org.zone".  Multiple url
+statements can be given, they are tried in turn.  If only urls are given
+the SOA refresh timer is used to wait for making new downloads.  If also
+masters are listed, the masters are first probed with UDP SOA queries to
+see if the SOA serial number has changed, reducing the number of downloads.
+If none of the urls work, the masters are tried with IXFR and AXFR.
+For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
+to authenticate the connection.
+.TP
+.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
+With allow\-notify you can specify additional sources of notifies.
+When notified, the server attempts to first probe and then zone transfer.
+If the notify is from a master, it first attempts that master.  Otherwise
+other masters are attempted.  If there are no masters, but only urls, the
+file is downloaded when notified.  The masters from master: statements are
+allowed notify by default.
+.TP
+.B zonefile: \fI<filename>
+The filename where the zone is stored.  If not given then no zonefile is used.
+If the file does not exist or is empty, unbound will attempt to fetch zone
+data (eg. from the master servers).
+.TP
+.B rpz\-action\-override: \fI<action>
+Always use this RPZ action for matching triggers from this zone. Possible action
+are: nxdomain, nodata, passthru, drop, disabled and cname.
+.TP
+.B rpz\-cname\-override: \fI<domain>
+The CNAME target domain to use if the cname action is configured for
+\fBrpz\-action\-override\fR.
+.TP
+.B rpz\-log: \fI<yes or no>
+Log all applied RPZ actions for this RPZ zone. Default is no.
+.TP
+.B rpz\-log\-name: \fI<name>
+Specify a string to be part of the log line, for easy referencing.
+.TP
+.B tags: \fI<list of tags>
+Limit the policies from this RPZ clause to clients with a matching tag. Tags
+need to be defined in \fBdefine\-tag\fR and can be assigned to client addresses
+using \fBaccess\-control\-tag\fR. Enclose list of tags in quotes ("") and put
+spaces between tags. If no tags are specified the policies from this clause will
+be applied for all clients.
 .SH "MEMORY CONTROL EXAMPLE"
 In the example config settings below memory usage is reduced. Some service
 levels are lower, notable very large data and a high TCP load are no longer
--- contrib/unbound/doc/unbound.doxygen.orig
+++ contrib/unbound/doc/unbound.doxygen
@@ -612,18 +612,24 @@
 
 EXCLUDE                = ./build \
                          ./compat \
+			 ./contrib \
                          util/configparser.c \
                          util/configparser.h \
                          util/configlexer.c \
                          util/locks.h \
+                         pythonmod/doc \
+                         pythonmod/examples \
                          pythonmod/unboundmodule.py \
                          pythonmod/interface.h \
-                         pythonmod/examples/resgen.py \
-                         pythonmod/examples/resmod.py \
-                         pythonmod/examples/resip.py \
+                         pythonmod/ubmodule-msg.py \
+                         pythonmod/ubmodule-tst.py \
+			 unboundmodule.py \
                          libunbound/python/unbound.py \
                          libunbound/python/libunbound_wrap.c \
+                         libunbound/python/doc \
+                         libunbound/python/examples \
                          ./ldns-src \
+			 README.md \
 			 doc/control_proto_spec.txt \
 			 doc/requirements.txt
 
--- contrib/unbound/edns-subnet/addrtree.c.orig
+++ contrib/unbound/edns-subnet/addrtree.c
@@ -119,7 +119,7 @@
 
 struct addrtree * 
 addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *), 
-	size_t (*sizefunc)(void *), void *env, unsigned int max_node_count)
+	size_t (*sizefunc)(void *), void *env, uint32_t max_node_count)
 {
 	struct addrtree *tree;
 	log_assert(delfunc != NULL);
--- contrib/unbound/edns-subnet/addrtree.h.orig
+++ contrib/unbound/edns-subnet/addrtree.h
@@ -66,10 +66,10 @@
 	struct addrnode *root;
 	/** Number of elements in the tree (not always equal to number of 
 	 * nodes) */
-	unsigned int node_count;
+	uint32_t node_count;
 	/** Maximum number of allowed nodes, will be enforced by LRU list.
 	 * Excluding the root node, 0 for unlimited */
-	unsigned int max_node_count;
+	uint32_t max_node_count;
 	/** Size of tree in bytes */
 	size_t size_bytes;
 	/** Maximum prefix length we are willing to cache. */
@@ -137,7 +137,7 @@
  */
 struct addrtree * 
 addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *), 
-	size_t (*sizefunc)(void *), void *env, unsigned int max_node_count);
+	size_t (*sizefunc)(void *), void *env, uint32_t max_node_count);
 
 /** 
  * Free tree and all nodes below.
--- contrib/unbound/edns-subnet/subnetmod.c.orig
+++ contrib/unbound/edns-subnet/subnetmod.c
@@ -55,9 +55,8 @@
 #include "util/config_file.h"
 #include "util/data/msgreply.h"
 #include "sldns/sbuffer.h"
+#include "iterator/iter_utils.h"
 
-#define ECS_MAX_TREESIZE 100
-
 /** externally called */
 void 
 subnet_data_delete(void *d, void *ATTR_UNUSED(arg))
@@ -93,6 +92,7 @@
 		return 0;
 	qstate->minfo[id] = sq;
 	memset(sq, 0, sizeof(*sq));
+	sq->started_no_cache_store = qstate->no_cache_store;
 	return 1;
 }
 
@@ -150,7 +150,9 @@
 
 	/* Cache by default, might be disabled after parsing EDNS option
 	 * received from nameserver. */
-	qstate->no_cache_store = 0;
+	if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo)) {
+		qstate->no_cache_store = 0;
+	}
 
 	if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream &&
 		qstate->env->cfg->client_subnet_always_forward) ||
@@ -177,6 +179,14 @@
 }
 
 
+void
+subnet_markdel(void* key)
+{
+	struct msgreply_entry *e = (struct msgreply_entry*)key;
+	e->key.qtype = 0;
+	e->key.qclass = 0;
+}
+
 int
 subnetmod_init(struct module_env *env, int id)
 {
@@ -193,6 +203,7 @@
 		HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
 		msg_cache_sizefunc, query_info_compare, query_entry_delete,
 		subnet_data_delete, NULL);
+	slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
 	if(!sn_env->subnet_msg_cache) {
 		log_err("subnet: could not create cache");
 		free(sn_env);
@@ -291,13 +302,13 @@
 		if (!data->tree4)
 			data->tree4 = addrtree_create(
 				cfg->max_client_subnet_ipv4, &delfunc,
-				&sizefunc, env, ECS_MAX_TREESIZE);
+				&sizefunc, env, cfg->max_ecs_tree_size_ipv4);
 		tree = data->tree4;
 	} else {
 		if (!data->tree6)
 			data->tree6 = addrtree_create(
 				cfg->max_client_subnet_ipv6, &delfunc,
-				&sizefunc, env, ECS_MAX_TREESIZE);
+				&sizefunc, env, cfg->max_ecs_tree_size_ipv6);
 		tree = data->tree6;
 	}
 	return tree;
@@ -323,33 +334,37 @@
 	/* Step 1, general qinfo lookup */
 	struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h,
 		&qstate->qinfo, 1);
-	int acquired_lock = (lru_entry != NULL);
+	int need_to_insert = (lru_entry == NULL);
 	if (!lru_entry) {
+		void* data = calloc(1,
+			sizeof(struct subnet_msg_cache_data));
+		if(!data) {
+			log_err("malloc failed");
+			return;
+		}
 		qinf = qstate->qinfo;
 		qinf.qname = memdup(qstate->qinfo.qname,
 			qstate->qinfo.qname_len);
 		if(!qinf.qname) {
+			free(data);
 			log_err("memdup failed");
 			return;
 		}
-		mrep_entry = query_info_entrysetup(&qinf, NULL, h);
+		mrep_entry = query_info_entrysetup(&qinf, data, h);
 		free(qinf.qname); /* if qname 'consumed', it is set to NULL */
 		if (!mrep_entry) {
+			free(data);
 			log_err("query_info_entrysetup failed");
 			return;
 		}
 		lru_entry = &mrep_entry->entry;
 		lock_rw_wrlock(&lru_entry->lock);
-		lru_entry->data = calloc(1,
-			sizeof(struct subnet_msg_cache_data));
-		if (!lru_entry->data) {
-			log_err("malloc failed");
-			return;
-		}
 	}
+	/* lru_entry->lock is locked regardless of how we got here,
+	 * either from the slabhash_lookup, or above in the new allocated */
 	/* Step 2, find the correct tree */
 	if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) {
-		if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
+		lock_rw_unlock(&lru_entry->lock);
 		log_err("Subnet cache insertion failed");
 		return;
 	}
@@ -357,7 +372,7 @@
 	rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL);
 	lock_quick_unlock(&sne->alloc.lock);
 	if (!rep) {
-		if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
+		lock_rw_unlock(&lru_entry->lock);
 		log_err("Subnet cache insertion failed");
 		return;
 	}
@@ -374,10 +389,9 @@
 		edns->subnet_source_mask, 
 		sq->ecs_server_in.subnet_scope_mask, rep,
 		rep->ttl, *qstate->env->now);
-	if (acquired_lock) {
-		lock_rw_unlock(&lru_entry->lock);
-	} else {
-		lock_rw_unlock(&lru_entry->lock);
+
+	lock_rw_unlock(&lru_entry->lock);
+	if (need_to_insert) {
 		slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data,
 			NULL);
 	}
@@ -417,7 +431,7 @@
 	}
 
 	qstate->return_msg = tomsg(NULL, &qstate->qinfo,
-		(struct reply_info *)node->elem, qstate->region, *env->now,
+		(struct reply_info *)node->elem, qstate->region, *env->now, 0,
 		env->scratch);
 	scope = (uint8_t)node->scope;
 	lock_rw_unlock(&e->lock);
@@ -487,9 +501,11 @@
 		 * is still usefull to put it in the edns subnet cache for
 		 * when a client explicitly asks for subnet specific answer. */
 		verbose(VERB_QUERY, "subnet: Authority indicates no support");
-		lock_rw_wrlock(&sne->biglock);
-		update_cache(qstate, id);
-		lock_rw_unlock(&sne->biglock);
+		if(!sq->started_no_cache_store) {
+			lock_rw_wrlock(&sne->biglock);
+			update_cache(qstate, id);
+			lock_rw_unlock(&sne->biglock);
+		}
 		if (sq->subnet_downstream)
 			cp_edns_bad_response(c_out, c_in);
 		return module_finished;
@@ -515,7 +531,9 @@
 	}
 
 	lock_rw_wrlock(&sne->biglock);
-	update_cache(qstate, id);
+	if(!sq->started_no_cache_store) {
+		update_cache(qstate, id);
+	}
 	sne->num_msg_nocache++;
 	lock_rw_unlock(&sne->biglock);
 	
@@ -526,6 +544,19 @@
 		c_out->subnet_source_mask = c_in->subnet_source_mask;
 		memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE);
 		c_out->subnet_scope_mask = s_in->subnet_scope_mask;
+		/* Limit scope returned to client to scope used for caching. */
+		if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
+			if(c_out->subnet_scope_mask >
+				qstate->env->cfg->max_client_subnet_ipv4) {
+				c_out->subnet_scope_mask =
+					qstate->env->cfg->max_client_subnet_ipv4;
+			}
+		}
+		else if(c_out->subnet_scope_mask >
+				qstate->env->cfg->max_client_subnet_ipv6) {
+				c_out->subnet_scope_mask =
+					qstate->env->cfg->max_client_subnet_ipv6;
+		}
 		c_out->subnet_validdata = 1;
 	}
 	return module_finished;
@@ -697,6 +728,17 @@
 			return;
 		}
 
+		/* Limit to minimum allowed source mask */
+		if(sq->ecs_client_in.subnet_source_mask != 0 && (
+			(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 &&
+			 sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv4) ||
+			(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6 &&
+			 sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv6))) {
+				qstate->return_rcode = LDNS_RCODE_REFUSED;
+				qstate->ext_state[id] = module_finished;
+				return;
+		}
+
 		lock_rw_wrlock(&sne->biglock);
 		if (lookup_and_reply(qstate, id, sq)) {
 			sne->num_msg_cache++;
@@ -753,6 +795,7 @@
 			ecs_opt_list_append(&sq->ecs_client_out,
 				&qstate->edns_opts_front_out, qstate);
 		}
+		qstate->no_cache_store = sq->started_no_cache_store;
 		return;
 	}
 	if(sq && outbound) {
--- contrib/unbound/edns-subnet/subnetmod.h.orig
+++ contrib/unbound/edns-subnet/subnetmod.h
@@ -83,6 +83,8 @@
 	struct ecs_data	ecs_server_out;
 	int subnet_downstream;
 	int subnet_sent;
+	/** has the subnet module been started with no_cache_store? */
+	int started_no_cache_store;
 };
 
 void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
@@ -131,4 +133,7 @@
 int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
 	int id, void* cbargs);
 
+/** mark subnet msg to be deleted */
+void subnet_markdel(void* key);
+
 #endif /* SUBNETMOD_H */
--- contrib/unbound/install-sh.orig
+++ contrib/unbound/install-sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/sh
 # install - install a program, script, or datafile
 
 scriptversion=2013-12-25.23; # UTC
--- contrib/unbound/ipsecmod/ipsecmod.c.orig
+++ contrib/unbound/ipsecmod/ipsecmod.c
@@ -103,11 +103,11 @@
 {
 	struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)regional_alloc(
 		qstate->region, sizeof(struct ipsecmod_qstate));
-	memset(iq, 0, sizeof(*iq));
 	qstate->minfo[id] = iq;
 	if(!iq)
 		return 0;
 	/* Initialise it. */
+	memset(iq, 0, sizeof(*iq));
 	iq->enabled = qstate->env->cfg->ipsecmod_enabled;
 	iq->is_whitelisted = ipsecmod_domain_is_whitelisted(
 		(struct ipsecmod_env*)qstate->env->modinfo[id], qstate->qinfo.qname,
@@ -162,6 +162,71 @@
 }
 
 /**
+ * Check if the string passed is a valid domain name with safe characters to
+ * pass to a shell.
+ * This will only allow:
+ *  - digits
+ *  - alphas
+ *  - hyphen (not at the start)
+ *  - dot (not at the start, or the only character)
+ *  - underscore
+ * @param s: pointer to the string.
+ * @param slen: string's length.
+ * @return true if s only contains safe characters; false otherwise.
+ */
+static int
+domainname_has_safe_characters(char* s, size_t slen) {
+	size_t i;
+	for(i = 0; i < slen; i++) {
+		if(s[i] == '\0') return 1;
+		if((s[i] == '-' && i != 0)
+			|| (s[i] == '.' && (i != 0 || s[1] == '\0'))
+			|| (s[i] == '_') || (s[i] >= '0' && s[i] <= '9')
+			|| (s[i] >= 'A' && s[i] <= 'Z')
+			|| (s[i] >= 'a' && s[i] <= 'z')) {
+			continue;
+		}
+		return 0;
+	}
+	return 1;
+}
+
+/**
+ * Check if the stringified IPSECKEY RDATA contains safe characters to pass to
+ * a shell.
+ * This is only relevant for checking the gateway when the gateway type is 3
+ * (domainname).
+ * @param s: pointer to the string.
+ * @param slen: string's length.
+ * @return true if s contains only safe characters; false otherwise.
+ */
+static int
+ipseckey_has_safe_characters(char* s, size_t slen) {
+	int precedence, gateway_type, algorithm;
+	char* gateway;
+	gateway = (char*)calloc(slen, sizeof(char));
+	if(!gateway) {
+		log_err("ipsecmod: out of memory when calling the hook");
+		return 0;
+	}
+	if(sscanf(s, "%d %d %d %s ",
+			&precedence, &gateway_type, &algorithm, gateway) != 4) {
+		free(gateway);
+		return 0;
+	}
+	if(gateway_type != 3) {
+		free(gateway);
+		return 1;
+	}
+	if(domainname_has_safe_characters(gateway, slen)) {
+		free(gateway);
+		return 1;
+	}
+	free(gateway);
+	return 0;
+}
+
+/**
  *  Prepare the data and call the hook.
  *
  *  @param qstate: query state.
@@ -175,7 +240,7 @@
 {
 	size_t slen, tempdata_len, tempstring_len, i;
 	char str[65535], *s, *tempstring;
-	int w;
+	int w = 0, w_temp, qtype;
 	struct ub_packed_rrset_key* rrset_key;
 	struct packed_rrset_data* rrset_data;
 	uint8_t *tempdata;
@@ -192,9 +257,9 @@
 	memset(s, 0, slen);
 
 	/* Copy the hook into the buffer. */
-	sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook);
+	w += sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook);
 	/* Put space into the buffer. */
-	sldns_str_print(&s, &slen, " ");
+	w += sldns_str_print(&s, &slen, " ");
 	/* Copy the qname into the buffer. */
 	tempstring = sldns_wire2str_dname(qstate->qinfo.qname,
 		qstate->qinfo.qname_len);
@@ -202,52 +267,69 @@
 		log_err("ipsecmod: out of memory when calling the hook");
 		return 0;
 	}
-	sldns_str_print(&s, &slen, "\"%s\"", tempstring);
+	if(!domainname_has_safe_characters(tempstring, strlen(tempstring))) {
+		log_err("ipsecmod: qname has unsafe characters");
+		free(tempstring);
+		return 0;
+	}
+	w += sldns_str_print(&s, &slen, "\"%s\"", tempstring);
 	free(tempstring);
 	/* Put space into the buffer. */
-	sldns_str_print(&s, &slen, " ");
+	w += sldns_str_print(&s, &slen, " ");
 	/* Copy the IPSECKEY TTL into the buffer. */
 	rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
-	sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl);
+	w += sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl);
 	/* Put space into the buffer. */
-	sldns_str_print(&s, &slen, " ");
-	/* Copy the A/AAAA record(s) into the buffer. Start and end this section
-	 * with a double quote. */
+	w += sldns_str_print(&s, &slen, " ");
 	rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo,
 		qstate->return_msg->rep);
+	/* Double check that the records are indeed A/AAAA.
+	 * This should never happen as this function is only executed for A/AAAA
+	 * queries but make sure we don't pass anything other than A/AAAA to the
+	 * shell. */
+	qtype = ntohs(rrset_key->rk.type);
+	if(qtype != LDNS_RR_TYPE_AAAA && qtype != LDNS_RR_TYPE_A) {
+		log_err("ipsecmod: Answer is not of A or AAAA type");
+		return 0;
+	}
 	rrset_data = (struct packed_rrset_data*)rrset_key->entry.data;
-	sldns_str_print(&s, &slen, "\"");
+	/* Copy the A/AAAA record(s) into the buffer. Start and end this section
+	 * with a double quote. */
+	w += sldns_str_print(&s, &slen, "\"");
 	for(i=0; i<rrset_data->count; i++) {
 		if(i > 0) {
 			/* Put space into the buffer. */
-			sldns_str_print(&s, &slen, " ");
+			w += sldns_str_print(&s, &slen, " ");
 		}
 		/* Ignore the first two bytes, they are the rr_data len. */
-		w = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2,
+		w_temp = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2,
 			rrset_data->rr_len[i] - 2, s, slen, qstate->qinfo.qtype);
-		if(w < 0) {
+		if(w_temp < 0) {
 			/* Error in printout. */
-			return -1;
-		} else if((size_t)w >= slen) {
+			log_err("ipsecmod: Error in printing IP address");
+			return 0;
+		} else if((size_t)w_temp >= slen) {
 			s = NULL; /* We do not want str to point outside of buffer. */
 			slen = 0;
-			return -1;
+			log_err("ipsecmod: shell command too long");
+			return 0;
 		} else {
-			s += w;
-			slen -= w;
+			s += w_temp;
+			slen -= w_temp;
+			w += w_temp;
 		}
 	}
-	sldns_str_print(&s, &slen, "\"");
+	w += sldns_str_print(&s, &slen, "\"");
 	/* Put space into the buffer. */
-	sldns_str_print(&s, &slen, " ");
+	w += sldns_str_print(&s, &slen, " ");
 	/* Copy the IPSECKEY record(s) into the buffer. Start and end this section
 	 * with a double quote. */
-	sldns_str_print(&s, &slen, "\"");
+	w += sldns_str_print(&s, &slen, "\"");
 	rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
 	for(i=0; i<rrset_data->count; i++) {
 		if(i > 0) {
 			/* Put space into the buffer. */
-			sldns_str_print(&s, &slen, " ");
+			w += sldns_str_print(&s, &slen, " ");
 		}
 		/* Ignore the first two bytes, they are the rr_data len. */
 		tempdata = rrset_data->rr_data[i] + 2;
@@ -254,16 +336,27 @@
 		tempdata_len = rrset_data->rr_len[i] - 2;
 		/* Save the buffer pointers. */
 		tempstring = s; tempstring_len = slen;
-		w = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, &slen,
-			NULL, 0);
+		w_temp = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s,
+			&slen, NULL, 0, NULL);
 		/* There was an error when parsing the IPSECKEY; reset the buffer
 		 * pointers to their previous values. */
-		if(w == -1){
+		if(w_temp == -1) {
 			s = tempstring; slen = tempstring_len;
+		} else if(w_temp > 0) {
+			if(!ipseckey_has_safe_characters(
+					tempstring, tempstring_len - slen)) {
+				log_err("ipsecmod: ipseckey has unsafe characters");
+				return 0;
+			}
+			w += w_temp;
 		}
 	}
-	sldns_str_print(&s, &slen, "\"");
-	verbose(VERB_ALGO, "ipsecmod: hook command: '%s'", str);
+	w += sldns_str_print(&s, &slen, "\"");
+	if(w >= (int)sizeof(str)) {
+		log_err("ipsecmod: shell command too long");
+		return 0;
+	}
+	verbose(VERB_ALGO, "ipsecmod: shell command: '%s'", str);
 	/* ipsecmod-hook should return 0 on success. */
 	if(system(str) != 0)
 		return 0;
--- contrib/unbound/ipset/ipset.c.orig
+++ contrib/unbound/ipset/ipset.c
@@ -0,0 +1,383 @@
+/**
+ * \file
+ * This file implements the ipset module.  It can handle packets by putting
+ * the A and AAAA addresses that are configured in unbound.conf as type
+ * ipset (local-zone statements) into a firewall rule IPSet.  For firewall
+ * blacklist and whitelist usage.
+ */
+#include "config.h"
+#include "ipset/ipset.h"
+#include "util/regional.h"
+#include "util/net_help.h"
+#include "util/config_file.h"
+
+#include "services/cache/dns.h"
+
+#include "sldns/sbuffer.h"
+#include "sldns/wire2str.h"
+#include "sldns/parseutil.h"
+
+#include <libmnl/libmnl.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/ipset/ip_set.h>
+
+#define BUFF_LEN 256
+
+/**
+ * Return an error
+ * @param qstate: our query state
+ * @param id: module id
+ * @param rcode: error code (DNS errcode).
+ * @return: 0 for use by caller, to make notation easy, like:
+ * 	return error_response(..).
+ */
+static int error_response(struct module_qstate* qstate, int id, int rcode) {
+	verbose(VERB_QUERY, "return error response %s",
+		sldns_lookup_by_id(sldns_rcodes, rcode)?
+		sldns_lookup_by_id(sldns_rcodes, rcode)->name:"??");
+	qstate->return_rcode = rcode;
+	qstate->return_msg = NULL;
+	qstate->ext_state[id] = module_finished;
+	return 0;
+}
+
+static struct mnl_socket * open_mnl_socket() {
+	struct mnl_socket *mnl;
+
+	mnl = mnl_socket_open(NETLINK_NETFILTER);
+	if (!mnl) {
+		log_err("ipset: could not open netfilter.");
+		return NULL;
+	}
+
+	if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
+		mnl_socket_close(mnl);
+		log_err("ipset: could not bind netfilter.");
+		return NULL;
+	}
+	return mnl;
+}
+
+static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
+	struct nlmsghdr *nlh;
+	struct nfgenmsg *nfg;
+	struct nlattr *nested[2];
+	static char buffer[BUFF_LEN];
+
+	if (strlen(setname) >= IPSET_MAXNAMELEN) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	if (af != AF_INET && af != AF_INET6) {
+		errno = EAFNOSUPPORT;
+		return -1;
+	}
+
+	nlh = mnl_nlmsg_put_header(buffer);
+	nlh->nlmsg_type = IPSET_CMD_ADD | (NFNL_SUBSYS_IPSET << 8);
+	nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL;
+
+	nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
+	nfg->nfgen_family = af;
+	nfg->version = NFNETLINK_V0;
+	nfg->res_id = htons(0);
+
+	mnl_attr_put_u8(nlh, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL);
+	mnl_attr_put(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname);
+	nested[0] = mnl_attr_nest_start(nlh, IPSET_ATTR_DATA);
+	nested[1] = mnl_attr_nest_start(nlh, IPSET_ATTR_IP);
+	mnl_attr_put(nlh, (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6)
+			| NLA_F_NET_BYTEORDER, (af == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr)), ipaddr);
+	mnl_attr_nest_end(nlh, nested[1]);
+	mnl_attr_nest_end(nlh, nested[0]);
+
+	if (mnl_socket_sendto(mnl, nlh, nlh->nlmsg_len) < 0) {
+		return -1;
+	}
+	return 0;
+}
+
+static void
+ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
+	struct packed_rrset_data *d, const char* setname, int af,
+	const char* dname)
+{
+	int ret;
+	size_t j, rr_len, rd_len;
+	uint8_t *rr_data;
+
+	/* to d->count, not d->rrsig_count, because we do not want to add the RRSIGs, only the addresses */
+	for (j = 0; j < d->count; j++) {
+		rr_len = d->rr_len[j];
+		rr_data = d->rr_data[j];
+
+		rd_len = sldns_read_uint16(rr_data);
+		if(af == AF_INET && rd_len != INET_SIZE)
+			continue;
+		if(af == AF_INET6 && rd_len != INET6_SIZE)
+			continue;
+		if (rr_len - 2 >= rd_len) {
+			if(verbosity >= VERB_QUERY) {
+				char ip[128];
+				if(inet_ntop(af, rr_data+2, ip, (socklen_t)sizeof(ip)) == 0)
+					snprintf(ip, sizeof(ip), "(inet_ntop_error)");
+				verbose(VERB_QUERY, "ipset: add %s to %s for %s", ip, setname, dname);
+			}
+			ret = add_to_ipset(mnl, setname, rr_data + 2, af);
+			if (ret < 0) {
+				log_err("ipset: could not add %s into %s", dname, setname);
+
+				mnl_socket_close(mnl);
+				ie->mnl = NULL;
+				break;
+			}
+		}
+	}
+}
+
+static int
+ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
+	struct mnl_socket *mnl, struct ub_packed_rrset_key *rrset,
+	const char *setname, int af)
+{
+	static char dname[BUFF_LEN];
+	const char *s;
+	int dlen, plen;
+
+	struct config_strlist *p;
+	struct packed_rrset_data *d;
+
+	dlen = sldns_wire2str_dname_buf(rrset->rk.dname, rrset->rk.dname_len, dname, BUFF_LEN);
+	if (dlen == 0) {
+		log_err("bad domain name");
+		return -1;
+	}
+	if (dname[dlen - 1] == '.') {
+		dlen--;
+	}
+
+	for (p = env->cfg->local_zones_ipset; p; p = p->next) {
+		plen = strlen(p->str);
+
+		if (dlen >= plen) {
+			s = dname + (dlen - plen);
+
+			if (strncasecmp(p->str, s, plen) == 0) {
+				d = (struct packed_rrset_data*)rrset->entry.data;
+				ipset_add_rrset_data(ie, mnl, d, setname,
+					af, dname);
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+static int ipset_update(struct module_env *env, struct dns_msg *return_msg, struct ipset_env *ie) {
+	struct mnl_socket *mnl;
+
+	size_t i;
+
+	const char *setname;
+
+	struct ub_packed_rrset_key *rrset;
+
+	int af;
+
+
+	mnl = (struct mnl_socket *)ie->mnl;
+	if (!mnl) {
+		// retry to create mnl socket
+		mnl = open_mnl_socket();
+		if (!mnl) {
+			return -1;
+		}
+
+		ie->mnl = mnl;
+	}
+
+	for (i = 0; i < return_msg->rep->rrset_count; ++i) {
+		setname = NULL;
+
+		rrset = return_msg->rep->rrsets[i];
+
+		if (rrset->rk.type == htons(LDNS_RR_TYPE_A)) {
+			af = AF_INET;
+			if ((ie->v4_enabled == 1)) {
+				setname = ie->name_v4;
+			}
+		} else {
+			af = AF_INET6;
+			if ((ie->v6_enabled == 1)) {
+				setname = ie->name_v6;
+			}
+		}
+
+		if (setname) {
+			if(ipset_check_zones_for_rrset(env, ie, mnl, rrset,
+				setname, af) == -1)
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+int ipset_init(struct module_env* env, int id) {
+	struct ipset_env *ipset_env;
+
+	ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
+	if (!ipset_env) {
+		log_err("malloc failure");
+		return 0;
+	}
+
+	env->modinfo[id] = (void *)ipset_env;
+
+	ipset_env->mnl = NULL;
+
+	ipset_env->name_v4 = env->cfg->ipset_name_v4;
+	ipset_env->name_v6 = env->cfg->ipset_name_v6;
+
+	ipset_env->v4_enabled = !ipset_env->name_v4 || (strlen(ipset_env->name_v4) == 0) ? 0 : 1;
+	ipset_env->v6_enabled = !ipset_env->name_v6 || (strlen(ipset_env->name_v6) == 0) ? 0 : 1;
+
+	if ((ipset_env->v4_enabled < 1) && (ipset_env->v6_enabled < 1)) {
+		log_err("ipset: set name no configuration?");
+		return 0;
+	}
+
+	return 1;
+}
+
+void ipset_deinit(struct module_env *env, int id) {
+	struct mnl_socket *mnl;
+	struct ipset_env *ipset_env;
+
+	if (!env || !env->modinfo[id]) {
+		return;
+	}
+
+	ipset_env = (struct ipset_env *)env->modinfo[id];
+
+	mnl = (struct mnl_socket *)ipset_env->mnl;
+	if (mnl) {
+		mnl_socket_close(mnl);
+		ipset_env->mnl = NULL;
+	}
+
+	free(ipset_env);
+	env->modinfo[id] = NULL;
+}
+
+static int ipset_new(struct module_qstate* qstate, int id) {
+	struct ipset_qstate *iq = (struct ipset_qstate *)regional_alloc(
+		qstate->region, sizeof(struct ipset_qstate));
+	qstate->minfo[id] = iq;
+	if (!iq) {
+		return 0;
+	}
+
+	memset(iq, 0, sizeof(*iq));
+	/* initialise it */
+	/* TODO */
+
+	return 1;
+}
+
+void ipset_operate(struct module_qstate *qstate, enum module_ev event, int id,
+	struct outbound_entry *outbound) {
+	struct ipset_env *ie = (struct ipset_env *)qstate->env->modinfo[id];
+	struct ipset_qstate *iq = (struct ipset_qstate *)qstate->minfo[id];
+	verbose(VERB_QUERY, "ipset[module %d] operate: extstate:%s event:%s",
+		id, strextstate(qstate->ext_state[id]), strmodulevent(event));
+	if (iq) {
+		log_query_info(VERB_QUERY, "ipset operate: query", &qstate->qinfo);
+	}
+
+	/* perform ipset state machine */
+	if ((event == module_event_new || event == module_event_pass) && !iq) {
+		if (!ipset_new(qstate, id)) {
+			(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+			return;
+		}
+		iq = (struct ipset_qstate*)qstate->minfo[id];
+	}
+
+	if (iq && (event == module_event_pass || event == module_event_new)) {
+		qstate->ext_state[id] = module_wait_module;
+		return;
+	}
+
+	if (iq && (event == module_event_moddone)) {
+		if (qstate->return_msg && qstate->return_msg->rep) {
+			ipset_update(qstate->env, qstate->return_msg, ie);
+		}
+		qstate->ext_state[id] = module_finished;
+		return;
+	}
+
+	if (iq && outbound) {
+		/* ipset does not need to process responses at this time
+		 * ignore it.
+		ipset_process_response(qstate, iq, ie, id, outbound, event);
+		*/
+		return;
+	}
+
+	if (event == module_event_error) {
+		verbose(VERB_ALGO, "got called with event error, giving up");
+		(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+		return;
+	}
+
+	if (!iq && (event == module_event_moddone)) {
+		/* during priming, module done but we never started */
+		qstate->ext_state[id] = module_finished;
+		return;
+	}
+
+	log_err("bad event for ipset");
+	(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+}
+
+void ipset_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
+	int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super)) {
+	/* ipset does not use subordinate requests at this time */
+	verbose(VERB_ALGO, "ipset inform_super was called");
+}
+
+void ipset_clear(struct module_qstate *qstate, int id) {
+	struct cachedb_qstate *iq;
+	if (!qstate) {
+		return;
+	}
+	iq = (struct cachedb_qstate *)qstate->minfo[id];
+	if (iq) {
+		/* free contents of iq */
+		/* TODO */
+	}
+	qstate->minfo[id] = NULL;
+}
+
+size_t ipset_get_mem(struct module_env *env, int id) {
+	struct ipset_env *ie = (struct ipset_env *)env->modinfo[id];
+	if (!ie) {
+		return 0;
+	}
+	return sizeof(*ie);
+}
+
+/**
+ * The ipset function block 
+ */
+static struct module_func_block ipset_block = {
+	"ipset",
+	&ipset_init, &ipset_deinit, &ipset_operate,
+	&ipset_inform_super, &ipset_clear, &ipset_get_mem
+};
+
+struct module_func_block * ipset_get_funcblock(void) {
+	return &ipset_block;
+}
+
--- contrib/unbound/ipset/ipset.h.orig
+++ contrib/unbound/ipset/ipset.h
@@ -0,0 +1,79 @@
+/**
+ * ipset.h
+ *
+ * Author: Kevin Chou
+ * Email: k9982874@gmail.com
+ */
+#ifndef IPSET_H
+#define IPSET_H
+/** \file
+ *
+ * This file implements the ipset module.  It can handle packets by putting
+ * the A and AAAA addresses that are configured in unbound.conf as type
+ * ipset (local-zone statements) into a firewall rule IPSet.  For firewall
+ * blacklist and whitelist usage.
+ *
+ * To use the IPset module, install the libmnl-dev (or libmnl-devel) package
+ * and configure with --enable-ipset.  And compile.  Then enable the ipset
+ * module in unbound.conf with module-config: "ipset validator iterator"
+ * then create it with ipset -N blacklist iphash and then add
+ * local-zone: "example.com." ipset
+ * statements for the zones where you want the addresses of the names
+ * looked up added to the set.
+ *
+ * Set the name of the set with
+ * ipset:
+ *   name-v4: "blacklist"
+ *   name-v6: "blacklist6"
+ * in unbound.conf.  The set can be used in this way:
+ *   iptables -A INPUT -m set --set blacklist src -j DROP
+ *   ip6tables -A INPUT -m set --set blacklist6 src -j DROP
+ */
+
+#include "util/module.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ipset_env {
+    void* mnl;
+
+	int v4_enabled;
+	int v6_enabled;
+
+	const char *name_v4;
+	const char *name_v6;
+};
+
+struct ipset_qstate {
+	int dummy;
+};
+
+/** Init the ipset module */
+int ipset_init(struct module_env* env, int id);
+/** Deinit the ipset module */
+void ipset_deinit(struct module_env* env, int id);
+/** Operate on an event on a query (in qstate). */
+void ipset_operate(struct module_qstate* qstate, enum module_ev event,
+	int id, struct outbound_entry* outbound);
+/** Subordinate query done, inform this super request of its conclusion */
+void ipset_inform_super(struct module_qstate* qstate, int id,
+	struct module_qstate* super);
+/** clear the ipset query-specific contents out of qstate */
+void ipset_clear(struct module_qstate* qstate, int id);
+/** return memory estimate for ipset module */
+size_t ipset_get_mem(struct module_env* env, int id);
+
+/**
+ * Get the function block with pointers to the ipset functions
+ * @return the function block for "ipset".
+ */
+struct module_func_block* ipset_get_funcblock(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IPSET_H */
+
--- contrib/unbound/iterator/iter_delegpt.c.orig
+++ contrib/unbound/iterator/iter_delegpt.c
@@ -84,7 +84,7 @@
 	}
 	for(a = dp->target_list; a; a = a->next_target) {
 		if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, 
-			a->bogus, a->lame, a->tls_auth_name))
+			a->bogus, a->lame, a->tls_auth_name, NULL))
 			return NULL;
 	}
 	return copy;
@@ -161,7 +161,7 @@
 int 
 delegpt_add_target(struct delegpt* dp, struct regional* region, 
 	uint8_t* name, size_t namelen, struct sockaddr_storage* addr, 
-	socklen_t addrlen, uint8_t bogus, uint8_t lame)
+	socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions)
 {
 	struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
 	log_assert(!dp->dp_type_mlc);
@@ -176,13 +176,14 @@
 		if(ns->got4 && ns->got6)
 			ns->resolved = 1;
 	}
-	return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
+	return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL,
+		additions);
 }
 
 int 
 delegpt_add_addr(struct delegpt* dp, struct regional* region, 
 	struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, 
-	uint8_t lame, char* tls_auth_name)
+	uint8_t lame, char* tls_auth_name, int* additions)
 {
 	struct delegpt_addr* a;
 	log_assert(!dp->dp_type_mlc);
@@ -194,6 +195,8 @@
 			a->lame = 0;
 		return 1;
 	}
+	if(additions)
+		*additions = 1;
 
 	a = (struct delegpt_addr*)regional_alloc(region,
 		sizeof(struct delegpt_addr));
@@ -382,10 +385,10 @@
 			continue;
 
 		if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) {
-			if(!delegpt_add_rrset_A(dp, region, s, 0))
+			if(!delegpt_add_rrset_A(dp, region, s, 0, NULL))
 				return NULL;
 		} else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) {
-			if(!delegpt_add_rrset_AAAA(dp, region, s, 0))
+			if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL))
 				return NULL;
 		}
 	}
@@ -416,7 +419,7 @@
 
 int 
 delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
-	struct ub_packed_rrset_key* ak, uint8_t lame)
+	struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
 {
         struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
         size_t i;
@@ -432,7 +435,7 @@
                 memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE);
                 if(!delegpt_add_target(dp, region, ak->rk.dname,
                         ak->rk.dname_len, (struct sockaddr_storage*)&sa,
-                        len, (d->security==sec_status_bogus), lame))
+                        len, (d->security==sec_status_bogus), lame, additions))
                         return 0;
         }
         return 1;
@@ -440,7 +443,7 @@
 
 int 
 delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
-	struct ub_packed_rrset_key* ak, uint8_t lame)
+	struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
 {
         struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
         size_t i;
@@ -456,7 +459,7 @@
                 memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE);
                 if(!delegpt_add_target(dp, region, ak->rk.dname,
                         ak->rk.dname_len, (struct sockaddr_storage*)&sa,
-                        len, (d->security==sec_status_bogus), lame))
+                        len, (d->security==sec_status_bogus), lame, additions))
                         return 0;
         }
         return 1;
@@ -464,7 +467,7 @@
 
 int 
 delegpt_add_rrset(struct delegpt* dp, struct regional* region,
-        struct ub_packed_rrset_key* rrset, uint8_t lame)
+        struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions)
 {
 	if(!rrset)
 		return 1;
@@ -471,13 +474,26 @@
 	if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)
 		return delegpt_rrset_add_ns(dp, region, rrset, lame);
 	else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)
-		return delegpt_add_rrset_A(dp, region, rrset, lame);
+		return delegpt_add_rrset_A(dp, region, rrset, lame, additions);
 	else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)
-		return delegpt_add_rrset_AAAA(dp, region, rrset, lame);
+		return delegpt_add_rrset_AAAA(dp, region, rrset, lame,
+			additions);
 	log_warn("Unknown rrset type added to delegpt");
 	return 1;
 }
 
+void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype)
+{
+	if(ns) {
+		if(qtype == LDNS_RR_TYPE_A)
+			ns->got4 = 2;
+		else if(qtype == LDNS_RR_TYPE_AAAA)
+			ns->got6 = 2;
+		if(ns->got4 && ns->got6)
+			ns->resolved = 1;
+	}
+}
+
 void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
 {
 	struct reply_info* rep = (struct reply_info*)msg->entry.data;
@@ -487,14 +503,7 @@
 	if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) {
 		struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, 
 			msg->key.qname_len);
-		if(ns) {
-			if(msg->key.qtype == LDNS_RR_TYPE_A)
-				ns->got4 = 1;
-			else if(msg->key.qtype == LDNS_RR_TYPE_AAAA)
-				ns->got6 = 1;
-			if(ns->got4 && ns->got6)
-				ns->resolved = 1;
-		}
+		delegpt_mark_neg(ns, msg->key.qtype);
 	}
 }
 
--- contrib/unbound/iterator/iter_delegpt.h.orig
+++ contrib/unbound/iterator/iter_delegpt.h
@@ -106,9 +106,10 @@
 	 * and marked true if got4 and got6 are both true.
 	 */
 	int resolved;
-	/** if the ipv4 address is in the delegpt */
+	/** if the ipv4 address is in the delegpt, 0=not, 1=yes 2=negative,
+	 * negative means it was done, but no content. */
 	uint8_t got4;
-	/** if the ipv6 address is in the delegpt */
+	/** if the ipv6 address is in the delegpt, 0=not, 1=yes 2=negative */
 	uint8_t got6;
 	/**
 	 * If the name is parent-side only and thus dispreferred.
@@ -215,11 +216,12 @@
  * @param addrlen: the length of addr.
  * @param bogus: security status for the address, pass true if bogus.
  * @param lame: address is lame.
+ * @param additions: will be set to 1 if a new address is added
  * @return false on error.
  */
 int delegpt_add_target(struct delegpt* dp, struct regional* regional, 
 	uint8_t* name, size_t namelen, struct sockaddr_storage* addr, 
-	socklen_t addrlen, uint8_t bogus, uint8_t lame);
+	socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions);
 
 /**
  * Add A RRset to delegpt.
@@ -227,10 +229,11 @@
  * @param regional: where to allocate the info.
  * @param rrset: RRset A to add.
  * @param lame: rrset is lame, disprefer it.
+ * @param additions: will be set to 1 if a new address is added
  * @return 0 on alloc error.
  */
 int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional, 
-	struct ub_packed_rrset_key* rrset, uint8_t lame);
+	struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
 
 /**
  * Add AAAA RRset to delegpt.
@@ -238,10 +241,11 @@
  * @param regional: where to allocate the info.
  * @param rrset: RRset AAAA to add.
  * @param lame: rrset is lame, disprefer it.
+ * @param additions: will be set to 1 if a new address is added
  * @return 0 on alloc error.
  */
 int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional, 
-	struct ub_packed_rrset_key* rrset, uint8_t lame);
+	struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
 
 /**
  * Add any RRset to delegpt.
@@ -250,10 +254,11 @@
  * @param regional: where to allocate the info.
  * @param rrset: RRset to add, NS, A, AAAA.
  * @param lame: rrset is lame, disprefer it.
+ * @param additions: will be set to 1 if a new address is added
  * @return 0 on alloc error.
  */
 int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, 
-	struct ub_packed_rrset_key* rrset, uint8_t lame);
+	struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
 
 /**
  * Add address to the delegation point. No servername is associated or checked.
@@ -264,11 +269,12 @@
  * @param bogus: if address is bogus.
  * @param lame: if address is lame.
  * @param tls_auth_name: TLS authentication name (or NULL).
+ * @param additions: will be set to 1 if a new address is added
  * @return false on error.
  */
 int delegpt_add_addr(struct delegpt* dp, struct regional* regional, 
 	struct sockaddr_storage* addr, socklen_t addrlen,
-	uint8_t bogus, uint8_t lame, char* tls_auth_name);
+	uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions);
 
 /** 
  * Find NS record in name list of delegation point.
@@ -342,6 +348,14 @@
 	struct regional* regional);
 
 /**
+ * Mark negative return in delegation point for specific nameserver.
+ * sets the got4 or got6 to negative, updates the ns->resolved.
+ * @param ns: the nameserver in the delegpt.
+ * @param qtype: A or AAAA (host order).
+ */
+void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype);
+
+/**
  * Add negative message to delegation point.
  * @param dp: delegation point.
  * @param msg: the message added, marks off A or AAAA from an NS entry.
--- contrib/unbound/iterator/iter_fwd.c.orig
+++ contrib/unbound/iterator/iter_fwd.c
@@ -239,7 +239,7 @@
 				s->name, p->str);
 			return 0;
 		}
-#ifndef HAVE_SSL_SET1_HOST
+#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
 		if(tls_auth_name)
 			log_err("no name verification functionality in "
 				"ssl library, ignored name for %s", p->str);
--- contrib/unbound/iterator/iter_hints.c.orig
+++ contrib/unbound/iterator/iter_hints.c
@@ -252,7 +252,7 @@
 				s->name, p->str);
 			return 0;
 		}
-#ifndef HAVE_SSL_SET1_HOST
+#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
 		if(auth_name)
 			log_err("no name verification functionality in "
 				"ssl library, ignored name for %s", p->str);
--- contrib/unbound/iterator/iter_scrub.c.orig
+++ contrib/unbound/iterator/iter_scrub.c
@@ -185,8 +185,9 @@
 /** Get target name of a CNAME */
 static int
 parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, 
-	size_t* snamelen)
+	size_t* snamelen, sldns_buffer* pkt)
 {
+	size_t oldpos, dlen;
 	if(rrset->rr_count != 1) {
 		struct rr_parse* sig;
 		verbose(VERB_ALGO, "Found CNAME rrset with "
@@ -204,6 +205,19 @@
 	*sname = rrset->rr_first->ttl_data + sizeof(uint32_t)
 		+ sizeof(uint16_t); /* skip ttl, rdatalen */
 	*snamelen = rrset->rr_first->size - sizeof(uint16_t);
+
+	if(rrset->rr_first->outside_packet) {
+		if(!dname_valid(*sname, *snamelen))
+			return 0;
+		return 1;
+	}
+	oldpos = sldns_buffer_position(pkt);
+	sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt)));
+	dlen = pkt_dname_len(pkt);
+	sldns_buffer_set_position(pkt, oldpos);
+	if(dlen == 0)
+		return 0; /* parse fail on the rdata name */
+	*snamelen = dlen;
 	return 1;
 }
 
@@ -215,8 +229,12 @@
 	/* we already know that sname is a strict subdomain of DNAME owner */
 	uint8_t* dtarg = NULL;
 	size_t dtarglen;
-	if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen))
+	if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt))
 		return 0; 
+	if(qnamelen <= dname_rrset->dname_len)
+		return 0;
+	if(qnamelen == 0)
+		return 0;
 	log_assert(qnamelen > dname_rrset->dname_len);
 	/* DNAME from com. to net. with qname example.com. -> example.net. */
 	/* so: \3com\0 to \3net\0 and qname \7example\3com\0 */
@@ -316,6 +334,18 @@
 	return dname_subdomain_c(zone, buf);
 }
 
+/** Check if there are SOA records in the authority section (negative) */
+static int
+soa_in_auth(struct msg_parse* msg)
+{
+	struct rrset_parse* rrset;
+	for(rrset = msg->rrset_first; rrset; rrset = rrset->rrset_all_next)
+		if(rrset->type == LDNS_RR_TYPE_SOA &&
+			rrset->section == LDNS_SECTION_AUTHORITY) 
+			return 1;
+	return 0;
+}
+
 /**
  * This routine normalizes a response. This includes removing "irrelevant"
  * records from the answer and additional sections and (re)synthesizing
@@ -372,7 +402,7 @@
 				/* check next cname */
 				uint8_t* t = NULL;
 				size_t tlen = 0;
-				if(!parse_get_cname_target(nx, &t, &tlen))
+				if(!parse_get_cname_target(nx, &t, &tlen, pkt))
 					return 0;
 				if(dname_pkt_compare(pkt, alias, t) == 0) {
 					/* it's OK and better capitalized */
@@ -423,7 +453,7 @@
 				size_t tlen = 0;
 				if(synth_cname(sname, snamelen, nx, alias,
 					&aliaslen, pkt) &&
-					parse_get_cname_target(rrset, &t, &tlen) &&
+					parse_get_cname_target(rrset, &t, &tlen, pkt) &&
 			   		dname_pkt_compare(pkt, alias, t) == 0) {
 					/* the synthesized CNAME equals the
 					 * current CNAME.  This CNAME is the
@@ -444,7 +474,7 @@
 			}
 
 			/* move to next name in CNAME chain */
-			if(!parse_get_cname_target(rrset, &sname, &snamelen))
+			if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt))
 				return 0;
 			prev = rrset;
 			rrset = rrset->rrset_all_next;
@@ -497,6 +527,19 @@
 					"RRset:", pkt, msg, prev, &rrset);
 				continue;
 			}
+			/* we don't want NS sets for NXDOMAIN answers,
+			 * because they could contain poisonous contents,
+			 * from. eg. fragmentation attacks, inserted after
+			 * long RRSIGs in the packet get to the packet
+			 * border and such */
+			/* also for NODATA answers */
+			if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN ||
+			   (FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR
+			    && soa_in_auth(msg) && msg->an_rrsets == 0)) {
+				remove_rrset("normalize: removing irrelevant "
+					"RRset:", pkt, msg, prev, &rrset);
+				continue;
+			}
 			if(nsset == NULL) {
 				nsset = rrset;
 			} else {
@@ -595,18 +638,6 @@
 	(void)rrset_cache_update(env->rrset_cache, &ref, env->alloc, now);
 }
 
-/** Check if there are SOA records in the authority section (negative) */
-static int
-soa_in_auth(struct msg_parse* msg)
-{
-	struct rrset_parse* rrset;
-	for(rrset = msg->rrset_first; rrset; rrset = rrset->rrset_all_next)
-		if(rrset->type == LDNS_RR_TYPE_SOA &&
-			rrset->section == LDNS_SECTION_AUTHORITY) 
-			return 1;
-	return 0;
-}
- 
 /**
  * Check if right hand name in NSEC is within zone
  * @param rrset: the NSEC rrset
--- contrib/unbound/iterator/iter_utils.c.orig
+++ contrib/unbound/iterator/iter_utils.c
@@ -282,10 +282,13 @@
 static int
 iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
 	uint8_t* name, size_t namelen, uint16_t qtype, time_t now, 
-	struct delegpt* dp, int* best_rtt, struct sock_list* blacklist)
+	struct delegpt* dp, int* best_rtt, struct sock_list* blacklist,
+	size_t* num_suitable_results)
 {
 	int got_it = 0;
 	struct delegpt_addr* a;
+	*num_suitable_results = 0;
+
 	if(dp->bogus)
 		return 0; /* NS bogus, all bogus, nothing found */
 	for(a=dp->result_list; a; a = a->next_result) {
@@ -301,11 +304,58 @@
 			} else if(a->sel_rtt < *best_rtt) {
 				*best_rtt = a->sel_rtt;
 			}
+			(*num_suitable_results)++;
 		}
 	}
 	return got_it;
 }
 
+/** compare two rtts, return -1, 0 or 1 */
+static int
+rtt_compare(const void* x, const void* y)
+{
+	if(*(int*)x == *(int*)y)
+		return 0;
+	if(*(int*)x > *(int*)y)
+		return 1;
+	return -1;
+}
+
+/** get RTT for the Nth fastest server */
+static int
+nth_rtt(struct delegpt_addr* result_list, size_t num_results, size_t n)
+{
+	int rtt_band;
+	size_t i;
+	int* rtt_list, *rtt_index;
+	
+	if(num_results < 1 || n >= num_results) {
+		return -1;
+	}
+
+	rtt_list = calloc(num_results, sizeof(int));
+	if(!rtt_list) {
+		log_err("malloc failure: allocating rtt_list");
+		return -1;
+	}
+	rtt_index = rtt_list;
+
+	for(i=0; i<num_results && result_list; i++) {
+		if(result_list->sel_rtt != -1) {
+			*rtt_index = result_list->sel_rtt;
+			rtt_index++;
+		}
+		result_list=result_list->next_result;
+	}
+	qsort(rtt_list, num_results, sizeof(*rtt_list), rtt_compare);
+
+	log_assert(n > 0);
+	rtt_band = rtt_list[n-1];
+	free(rtt_list);
+
+	return rtt_band;
+}
+
 /** filter the address list, putting best targets at front,
  * returns number of best targets (or 0, no suitable targets) */
 static int
@@ -314,12 +364,13 @@
 	struct delegpt* dp, int* selected_rtt, int open_target, 
 	struct sock_list* blacklist, time_t prefetch)
 {
-	int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
+	int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND, nth;
+	size_t num_results;
 	struct delegpt_addr* a, *n, *prev=NULL;
 
 	/* fillup sel_rtt and find best rtt in the bunch */
 	got_num = iter_fill_rtt(iter_env, env, name, namelen, qtype, now, dp, 
-		&low_rtt, blacklist);
+		&low_rtt, blacklist, &num_results);
 	if(got_num == 0) 
 		return 0;
 	if(low_rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
@@ -329,14 +380,19 @@
 			     return 0 to force the caller to fetch more */
 	}
 
-	if(env->cfg->low_rtt_permil != 0 && prefetch == 0 &&
-		low_rtt < env->cfg->low_rtt &&
-		ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_permil) {
+	if(env->cfg->fast_server_permil != 0 && prefetch == 0 &&
+		num_results > env->cfg->fast_server_num &&
+		ub_random_max(env->rnd, 1000) < env->cfg->fast_server_permil) {
 		/* the query is not prefetch, but for a downstream client,
-		 * there is a low_rtt (fast) server.  We choose that x% of the
-		 * time */
-		/* pick rtt numbers from 0..LOWBAND_RTT */
-		rtt_band = env->cfg->low_rtt - low_rtt;
+		 * there are more servers available then the fastest N we want
+		 * to choose from. Limit our choice to the fastest servers. */
+		nth = nth_rtt(dp->result_list, num_results,
+			env->cfg->fast_server_num);
+		if(nth > 0) {
+			rtt_band = nth - low_rtt;
+			if(rtt_band > RTT_BAND)
+				rtt_band = RTT_BAND;
+		}
 	}
 
 	got_num = 0;
@@ -826,10 +882,35 @@
 	return 1;
 }
 
+/** compare rrsets and sort canonically.  Compares rrset name, type, class.
+ * return 0 if equal, +1 if x > y, and -1 if x < y.
+ */
+static int
+rrset_canonical_sort_cmp(const void* x, const void* y)
+{
+	struct ub_packed_rrset_key* rrx = *(struct ub_packed_rrset_key**)x;
+	struct ub_packed_rrset_key* rry = *(struct ub_packed_rrset_key**)y;
+	int r = dname_canonical_compare(rrx->rk.dname, rry->rk.dname);
+	if(r != 0)
+		return r;
+	if(rrx->rk.type != rry->rk.type) {
+		if(ntohs(rrx->rk.type) > ntohs(rry->rk.type))
+			return 1;
+		else	return -1;
+	}
+	if(rrx->rk.rrset_class != rry->rk.rrset_class) {
+		if(ntohs(rrx->rk.rrset_class) > ntohs(rry->rk.rrset_class))
+			return 1;
+		else	return -1;
+	}
+	return 0;
+}
+
 int 
 reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
 {
 	size_t i;
+	struct ub_packed_rrset_key** sorted_p, **sorted_q;
 	if(p->flags != q->flags ||
 		p->qdcount != q->qdcount ||
 		/* do not check TTL, this may differ */
@@ -843,16 +924,43 @@
 		p->ar_numrrsets != q->ar_numrrsets ||
 		p->rrset_count != q->rrset_count)
 		return 0;
+	/* sort the rrsets in the authority and additional sections before
+	 * compare, the query and answer sections are ordered in the sequence
+	 * they should have (eg. one after the other for aliases). */
+	sorted_p = (struct ub_packed_rrset_key**)regional_alloc_init(
+		region, p->rrsets, sizeof(*sorted_p)*p->rrset_count);
+	if(!sorted_p) return 0;
+	log_assert(p->an_numrrsets + p->ns_numrrsets + p->ar_numrrsets <=
+		p->rrset_count);
+	qsort(sorted_p + p->an_numrrsets, p->ns_numrrsets,
+		sizeof(*sorted_p), rrset_canonical_sort_cmp);
+	qsort(sorted_p + p->an_numrrsets + p->ns_numrrsets, p->ar_numrrsets,
+		sizeof(*sorted_p), rrset_canonical_sort_cmp);
+
+	sorted_q = (struct ub_packed_rrset_key**)regional_alloc_init(
+		region, q->rrsets, sizeof(*sorted_q)*q->rrset_count);
+	if(!sorted_q) {
+		regional_free_all(region);
+		return 0;
+	}
+	log_assert(q->an_numrrsets + q->ns_numrrsets + q->ar_numrrsets <=
+		q->rrset_count);
+	qsort(sorted_q + q->an_numrrsets, q->ns_numrrsets,
+		sizeof(*sorted_q), rrset_canonical_sort_cmp);
+	qsort(sorted_q + q->an_numrrsets + q->ns_numrrsets, q->ar_numrrsets,
+		sizeof(*sorted_q), rrset_canonical_sort_cmp);
+
+	/* compare the rrsets */
 	for(i=0; i<p->rrset_count; i++) {
-		if(!rrset_equal(p->rrsets[i], q->rrsets[i])) {
-			if(!rrset_canonical_equal(region, p->rrsets[i],
-				q->rrsets[i])) {
+		if(!rrset_equal(sorted_p[i], sorted_q[i])) {
+			if(!rrset_canonical_equal(region, sorted_p[i],
+				sorted_q[i])) {
 				regional_free_all(region);
 				return 0;
 			}
-			regional_free_all(region);
 		}
 	}
+	regional_free_all(region);
 	return 1;
 }
 
@@ -1034,7 +1142,7 @@
 			log_rrset_key(VERB_ALGO, "found parent-side", akey);
 			ns->done_pside4 = 1;
 			/* a negative-cache-element has no addresses it adds */
-			if(!delegpt_add_rrset_A(dp, region, akey, 1))
+			if(!delegpt_add_rrset_A(dp, region, akey, 1, NULL))
 				log_err("malloc failure in lookup_parent_glue");
 			lock_rw_unlock(&akey->entry.lock);
 		}
@@ -1046,7 +1154,7 @@
 			log_rrset_key(VERB_ALGO, "found parent-side", akey);
 			ns->done_pside6 = 1;
 			/* a negative-cache-element has no addresses it adds */
-			if(!delegpt_add_rrset_AAAA(dp, region, akey, 1))
+			if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, NULL))
 				log_err("malloc failure in lookup_parent_glue");
 			lock_rw_unlock(&akey->entry.lock);
 		}
@@ -1103,6 +1211,19 @@
 	}
 }
 
+void
+iter_scrub_nxdomain(struct dns_msg* msg)
+{
+	if(msg->rep->an_numrrsets == 0)
+		return;
+
+	memmove(msg->rep->rrsets, msg->rep->rrsets+msg->rep->an_numrrsets,
+		sizeof(struct ub_packed_rrset_key*) *
+		(msg->rep->rrset_count-msg->rep->an_numrrsets));
+	msg->rep->rrset_count -= msg->rep->an_numrrsets;
+	msg->rep->an_numrrsets = 0;
+}
+
 void iter_dec_attempts(struct delegpt* dp, int d)
 {
 	struct delegpt_addr* a;
@@ -1210,3 +1331,50 @@
 		return 0;
 	return 1;
 }
+
+int
+iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf)
+{
+	struct iter_hints_stub *stub;
+	struct delegpt *dp;
+
+	/* Check for stub. */
+	stub = hints_lookup_stub(qstate->env->hints, qinf->qname,
+	    qinf->qclass, NULL);
+	dp = forwards_lookup(qstate->env->fwds, qinf->qname, qinf->qclass);
+
+	/* see if forward or stub is more pertinent */
+	if(stub && stub->dp && dp) {
+		if(dname_strict_subdomain(dp->name, dp->namelabs,
+			stub->dp->name, stub->dp->namelabs)) {
+			stub = NULL; /* ignore stub, forward is lower */
+		} else {
+			dp = NULL; /* ignore forward, stub is lower */
+		}
+	}
+
+	/* check stub */
+	if (stub != NULL && stub->dp != NULL) {
+		if(stub->dp->no_cache) {
+			char qname[255+1];
+			char dpname[255+1];
+			dname_str(qinf->qname, qname);
+			dname_str(stub->dp->name, dpname);
+			verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
+		}
+		return (stub->dp->no_cache);
+	}
+
+	/* Check for forward. */
+	if (dp) {
+		if(dp->no_cache) {
+			char qname[255+1];
+			char dpname[255+1];
+			dname_str(qinf->qname, qname);
+			dname_str(dp->name, dpname);
+			verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
+		}
+		return (dp->no_cache);
+	}
+	return 0;
+}
--- contrib/unbound/iterator/iter_utils.h.orig
+++ contrib/unbound/iterator/iter_utils.h
@@ -335,6 +335,13 @@
 	uint8_t* z);
 
 /**
+ * Prepare an NXDOMAIN message to be used for a subdomain answer by removing all
+ * RRs from the ANSWER section.
+ * @param msg: the response to scrub.
+ */
+void iter_scrub_nxdomain(struct dns_msg* msg);
+
+/**
  * Remove query attempts from all available ips. For 0x20.
  * @param dp: delegpt.
  * @param d: decrease.
@@ -369,4 +376,13 @@
  */
 int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp);
 
+/** 
+ * Lookup if no_cache is set in stub or fwd.
+ * @param qstate: query state with env with hints and fwds.
+ * @param qinf: query name to lookup for.
+ * @return true if no_cache is set in stub or fwd.
+ */
+int iter_stub_fwd_no_cache(struct module_qstate *qstate,
+	struct query_info *qinf);
+
 #endif /* ITERATOR_ITER_UTILS_H */
--- contrib/unbound/iterator/iterator.c.orig
+++ contrib/unbound/iterator/iterator.c
@@ -69,6 +69,11 @@
 #include "sldns/parseutil.h"
 #include "sldns/sbuffer.h"
 
+/* in msec */
+int UNKNOWN_SERVER_NICENESS = 376;
+
+static void target_count_increase_nx(struct iter_qstate* iq, int num);
+
 int 
 iter_init(struct module_env* env, int id)
 {
@@ -147,6 +152,7 @@
 	iq->sent_count = 0;
 	iq->ratelimit_ok = 0;
 	iq->target_count = NULL;
+	iq->dp_target_count = 0;
 	iq->wait_priming_stub = 0;
 	iq->refetch_glue = 0;
 	iq->dnssec_expected = 0;
@@ -218,6 +224,7 @@
 static void
 error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
 {
+	struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
 	struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
 
 	if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
@@ -243,7 +250,11 @@
 				super->region, super_iq->dp))
 				log_err("out of memory adding missing");
 		}
+		delegpt_mark_neg(dpns, qstate->qinfo.qtype);
 		dpns->resolved = 1; /* mark as failed */
+		if((dpns->got4 == 2 || !ie->supports_ipv4) &&
+			(dpns->got6 == 2 || !ie->supports_ipv6))
+			target_count_increase_nx(super_iq, 1);
 	}
 	if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
 		/* prime failed to get delegation */
@@ -324,6 +335,29 @@
 			/* serving expired contents, but nothing is cached
 			 * at all, so the servfail cache entry is useful
 			 * (stops waste of time on this servfail NORR_TTL) */
+		} else {
+			/* don't overwrite existing (non-expired) data in
+			 * cache with a servfail */
+			struct msgreply_entry* msg;
+			if((msg=msg_cache_lookup(qstate->env,
+				qstate->qinfo.qname, qstate->qinfo.qname_len,
+				qstate->qinfo.qtype, qstate->qinfo.qclass,
+				qstate->query_flags, *qstate->env->now, 0))
+				!= NULL) {
+				struct reply_info* rep = (struct reply_info*)
+					msg->entry.data;
+				if(FLAGS_GET_RCODE(rep->flags) ==
+					LDNS_RCODE_NOERROR ||
+					FLAGS_GET_RCODE(rep->flags) ==
+					LDNS_RCODE_NXDOMAIN) {
+					/* we have a good entry,
+					 * don't overwrite */
+					lock_rw_unlock(&msg->entry.lock);
+					return error_response(qstate, id, rcode);
+				}
+				lock_rw_unlock(&msg->entry.lock);
+			}
+			
 		}
 		memset(&err, 0, sizeof(err));
 		err.flags = (uint16_t)(BIT_QR | BIT_RA);
@@ -383,6 +417,8 @@
 	num_an = 0;
 	for(p = iq->an_prepend_list; p; p = p->next) {
 		sets[num_an++] = p->rrset;
+		if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
+			msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
 	}
 	memcpy(sets+num_an, msg->rep->rrsets, msg->rep->an_numrrsets *
 		sizeof(struct ub_packed_rrset_key*));
@@ -395,6 +431,8 @@
 			msg->rep->ns_numrrsets, p->rrset))
 			continue;
 		sets[msg->rep->an_numrrsets + num_an + num_ns++] = p->rrset;
+		if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
+			msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
 	}
 	memcpy(sets + num_an + msg->rep->an_numrrsets + num_ns, 
 		msg->rep->rrsets + msg->rep->an_numrrsets, 
@@ -591,7 +629,7 @@
 target_count_create(struct iter_qstate* iq)
 {
 	if(!iq->target_count) {
-		iq->target_count = (int*)calloc(2, sizeof(int));
+		iq->target_count = (int*)calloc(3, sizeof(int));
 		/* if calloc fails we simply do not track this number */
 		if(iq->target_count)
 			iq->target_count[0] = 1;
@@ -604,8 +642,17 @@
 	target_count_create(iq);
 	if(iq->target_count)
 		iq->target_count[1] += num;
+	iq->dp_target_count++;
 }
 
+static void
+target_count_increase_nx(struct iter_qstate* iq, int num)
+{
+	target_count_create(iq);
+	if(iq->target_count)
+		iq->target_count[2] += num;
+}
+
 /**
  * Generate a subrequest.
  * Generate a local request event. Local events are tied to this module, and
@@ -626,6 +673,7 @@
  * @param subq_ret: if newly allocated, the subquerystate, or NULL if it does
  * 	not need initialisation.
  * @param v: if true, validation is done on the subquery.
+ * @param detached: true if this qstate should not attach to the subquery
  * @return false on error (malloc).
  */
 static int
@@ -632,7 +680,8 @@
 generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, 
 	uint16_t qclass, struct module_qstate* qstate, int id,
 	struct iter_qstate* iq, enum iter_state initial_state, 
-	enum iter_state finalstate, struct module_qstate** subq_ret, int v)
+	enum iter_state finalstate, struct module_qstate** subq_ret, int v,
+	int detached)
 {
 	struct module_qstate* subq = NULL;
 	struct iter_qstate* subiq = NULL;
@@ -659,12 +708,24 @@
 		valrec = 1;
 	}
 	
-	/* attach subquery, lookup existing or make a new one */
-	fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
-	if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
-		&subq)) {
-		return 0;
+	if(detached) {
+		struct mesh_state* sub = NULL;
+		fptr_ok(fptr_whitelist_modenv_add_sub(
+			qstate->env->add_sub));
+		if(!(*qstate->env->add_sub)(qstate, &qinf,
+			qflags, prime, valrec, &subq, &sub)){
+			return 0;
+		}
 	}
+	else {
+		/* attach subquery, lookup existing or make a new one */
+		fptr_ok(fptr_whitelist_modenv_attach_sub(
+			qstate->env->attach_sub));
+		if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,
+			valrec, &subq)) {
+			return 0;
+		}
+	}
 	*subq_ret = subq;
 	if(subq) {
 		/* initialise the new subquery */
@@ -686,6 +747,7 @@
 		subiq->target_count = iq->target_count;
 		if(iq->target_count)
 			iq->target_count[0] ++; /* extra reference */
+		subiq->dp_target_count = 0;
 		subiq->num_current_queries = 0;
 		subiq->depth = iq->depth+1;
 		outbound_list_init(&subiq->outlist);
@@ -729,7 +791,7 @@
 	 * the normal INIT state logic (which would cause an infloop). */
 	if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS, 
 		qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE,
-		&subq, 0)) {
+		&subq, 0, 0)) {
 		verbose(VERB_ALGO, "could not prime root");
 		return 0;
 	}
@@ -820,7 +882,7 @@
 	 * redundant INIT state processing. */
 	if(!generate_sub_request(stub_dp->name, stub_dp->namelen, 
 		LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
-		QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
+		QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0, 0)) {
 		verbose(VERB_ALGO, "could not prime stub");
 		errinf(qstate, "could not generate lookup for stub prime");
 		(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
@@ -995,7 +1057,7 @@
 		if(!generate_sub_request(s->rk.dname, s->rk.dname_len, 
 			ntohs(s->rk.type), ntohs(s->rk.rrset_class),
 			qstate, id, iq,
-			INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
+			INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
 			verbose(VERB_ALGO, "could not generate addr check");
 			return;
 		}
@@ -1039,7 +1101,7 @@
 		iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
 	if(!generate_sub_request(iq->dp->name, iq->dp->namelen, 
 		LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
-		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
+		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
 		verbose(VERB_ALGO, "could not generate ns check");
 		return;
 	}
@@ -1096,7 +1158,7 @@
 		iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass);
 	if(!generate_sub_request(iq->dp->name, iq->dp->namelen, 
 		LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq,
-		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {
+		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {
 		/* we'll be slower, but it'll work */
 		verbose(VERB_ALGO, "could not generate dnskey prefetch");
 		return;
@@ -1144,53 +1206,6 @@
 	return 1;
 }
 
-static int
-iter_stub_fwd_no_cache(struct module_qstate *qstate, struct iter_qstate *iq)
-{
-	struct iter_hints_stub *stub;
-	struct delegpt *dp;
-
-	/* Check for stub. */
-	stub = hints_lookup_stub(qstate->env->hints, iq->qchase.qname,
-	    iq->qchase.qclass, iq->dp);
-	dp = forwards_lookup(qstate->env->fwds, iq->qchase.qname, iq->qchase.qclass);
-
-	/* see if forward or stub is more pertinent */
-	if(stub && stub->dp && dp) {
-		if(dname_strict_subdomain(dp->name, dp->namelabs,
-			stub->dp->name, stub->dp->namelabs)) {
-			stub = NULL; /* ignore stub, forward is lower */
-		} else {
-			dp = NULL; /* ignore forward, stub is lower */
-		}
-	}
-
-	/* check stub */
-	if (stub != NULL && stub->dp != NULL) {
-		if(stub->dp->no_cache) {
-			char qname[255+1];
-			char dpname[255+1];
-			dname_str(iq->qchase.qname, qname);
-			dname_str(stub->dp->name, dpname);
-			verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
-		}
-		return (stub->dp->no_cache);
-	}
-
-	/* Check for forward. */
-	if (dp) {
-		if(dp->no_cache) {
-			char qname[255+1];
-			char dpname[255+1];
-			dname_str(iq->qchase.qname, qname);
-			dname_str(dp->name, dpname);
-			verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
-		}
-		return (dp->no_cache);
-	}
-	return 0;
-}
-
 /** 
  * Process the initial part of the request handling. This state roughly
  * corresponds to resolver algorithms steps 1 (find answer in cache) and 2
@@ -1268,7 +1283,7 @@
 	/* This either results in a query restart (CNAME cache response), a
 	 * terminating response (ANSWER), or a cache miss (null). */
 	
-	if (iter_stub_fwd_no_cache(qstate, iq)) {
+	if (iter_stub_fwd_no_cache(qstate, &iq->qchase)) {
 		/* Asked to not query cache. */
 		verbose(VERB_ALGO, "no-cache set, going to the network");
 		qstate->no_cache_lookup = 1;
@@ -1332,6 +1347,7 @@
 			iq->refetch_glue = 0;
 			iq->query_restart_count++;
 			iq->sent_count = 0;
+			iq->dp_target_count = 0;
 			sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
 			if(qstate->env->cfg->qname_minimisation)
 				iq->minimisation_state = INIT_MINIMISE_STATE;
@@ -1469,7 +1485,8 @@
 			 * now will also exceed the rate, keeping cache fresh */
 			(void)infra_ratelimit_inc(qstate->env->infra_cache,
 				iq->dp->name, iq->dp->namelen,
-				*qstate->env->now);
+				*qstate->env->now, &qstate->qinfo,
+				qstate->reply);
 			/* see if we are passed through with slip factor */
 			if(qstate->env->cfg->ratelimit_factor != 0 &&
 				ub_random_max(qstate->env->rnd,
@@ -1709,7 +1726,7 @@
 {
 	struct module_qstate* subq;
 	if(!generate_sub_request(name, namelen, qtype, qclass, qstate, 
-		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
+		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
 		return 0;
 	if(subq) {
 		struct iter_qstate* subiq = 
@@ -1760,7 +1777,7 @@
 {
 	struct module_qstate* subq;
 	if(!generate_sub_request(name, namelen, qtype, qclass, qstate, 
-		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
+		id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
 		return 0;
 	log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass);
 	return 1;
@@ -1799,6 +1816,14 @@
 			"number of glue fetches %d", s, iq->target_count[1]);
 		return 0;
 	}
+	if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
+		char s[LDNS_MAX_DOMAINLEN+1];
+		dname_str(qstate->qinfo.qname, s);
+		verbose(VERB_QUERY, "request %s has exceeded the maximum "
+			"number of glue fetches %d to a single delegation point",
+			s, iq->dp_target_count);
+		return 0;
+	}
 
 	iter_mark_cycle_targets(qstate, iq->dp);
 	missing = (int)delegpt_count_missing_targets(iq->dp);
@@ -1903,7 +1928,6 @@
 		struct delegpt* p = hints_lookup_root(qstate->env->hints,
 			iq->qchase.qclass);
 		if(p) {
-			struct delegpt_ns* ns;
 			struct delegpt_addr* a;
 			iq->chase_flags &= ~BIT_RD; /* go to authorities */
 			for(ns = p->nslist; ns; ns=ns->next) {
@@ -1913,7 +1937,7 @@
 			for(a = p->target_list; a; a=a->next_target) {
 				(void)delegpt_add_addr(iq->dp, qstate->region,
 					&a->addr, a->addrlen, a->bogus,
-					a->lame, a->tls_auth_name);
+					a->lame, a->tls_auth_name, NULL);
 			}
 		}
 		iq->dp->has_parent_side_NS = 1;
@@ -1930,6 +1954,7 @@
 			iq->refetch_glue = 1;
 			iq->query_restart_count++;
 			iq->sent_count = 0;
+			iq->dp_target_count = 0;
 			if(qstate->env->cfg->qname_minimisation)
 				iq->minimisation_state = INIT_MINIMISE_STATE;
 			return next_state(iq, INIT_REQUEST_STATE);
@@ -2095,7 +2120,7 @@
 		iq->dsns_point, LDNS_RR_TYPE_NS, iq->qchase.qclass);
 	if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len, 
 		LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
-		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {
+		INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {
 		errinf_dname(qstate, "for DS query parent-child nameserver search, could not generate NS lookup for", iq->dsns_point);
 		return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
 	}
@@ -2127,6 +2152,8 @@
 	struct delegpt_addr* target;
 	struct outbound_entry* outq;
 	int auth_fallback = 0;
+	uint8_t* qout_orig = NULL;
+	size_t qout_orig_len = 0;
 
 	/* NOTE: a request will encounter this state for each target it 
 	 * needs to send a query to. That is, at least one per referral, 
@@ -2151,6 +2178,13 @@
 		errinf(qstate, "exceeded the maximum number of sends");
 		return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
 	}
+	if(iq->target_count && iq->target_count[2] > MAX_TARGET_NX) {
+		verbose(VERB_QUERY, "request has exceeded the maximum "
+			" number of nxdomain nameserver lookups with %d",
+			iq->target_count[2]);
+		errinf(qstate, "exceeded the maximum nameserver nxdomains");
+		return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+	}
 	
 	/* Make sure we have a delegation point, otherwise priming failed
 	 * or another failure occurred */
@@ -2200,6 +2234,8 @@
 		int labdiff = qchaselabs -
 			dname_count_labels(iq->qinfo_out.qname);
 
+		qout_orig = iq->qinfo_out.qname;
+		qout_orig_len = iq->qinfo_out.qname_len;
 		iq->qinfo_out.qname = iq->qchase.qname;
 		iq->qinfo_out.qname_len = iq->qchase.qname_len;
 		iq->minimise_count++;
@@ -2253,12 +2289,41 @@
 				iq->qinfo_out.qtype, iq->qinfo_out.qclass, 
 				qstate->query_flags, qstate->region, 
 				qstate->env->scratch, 0);
-			if(msg && msg->rep->an_numrrsets == 0
-				&& FLAGS_GET_RCODE(msg->rep->flags) == 
+			if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
 				LDNS_RCODE_NOERROR)
 				/* no need to send query if it is already 
-				 * cached as NOERROR/NODATA */
+				 * cached as NOERROR */
 				return 1;
+			if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
+				LDNS_RCODE_NXDOMAIN &&
+				qstate->env->need_to_validate &&
+				qstate->env->cfg->harden_below_nxdomain) {
+				if(msg->rep->security == sec_status_secure) {
+					iq->response = msg;
+					return final_state(iq);
+				}
+				if(msg->rep->security == sec_status_unchecked) {
+					struct module_qstate* subq = NULL;
+					if(!generate_sub_request(
+						iq->qinfo_out.qname,
+						iq->qinfo_out.qname_len,
+						iq->qinfo_out.qtype,
+						iq->qinfo_out.qclass,
+						qstate, id, iq,
+						INIT_REQUEST_STATE,
+						FINISHED_STATE, &subq, 1, 1))
+						verbose(VERB_ALGO,
+						"could not validate NXDOMAIN "
+						"response");
+				}
+			}
+			if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
+				LDNS_RCODE_NXDOMAIN) {
+				/* return and add a label in the next
+				 * minimisation iteration.
+				 */
+				return 1;
+			}
 		}
 	}
 	if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
@@ -2320,7 +2385,7 @@
 		errinf(qstate, "auth zone lookup failed, fallback is off");
 		return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
 	}
-	if(iq->dp && iq->dp->auth_dp) {
+	if(iq->dp->auth_dp) {
 		/* we wanted to fallback, but had no delegpt, only the
 		 * auth zone generated delegpt, create an actual one */
 		iq->auth_zone_avoid = 1;
@@ -2334,6 +2399,8 @@
 	 * generated query will immediately be discarded due to depth and
 	 * that servfail is cached, which is not good as opportunism goes. */
 	if(iq->depth < ie->max_dependency_depth
+		&& iq->num_target_queries == 0
+		&& (!iq->target_count || iq->target_count[2]==0)
 		&& iq->sent_count < TARGET_FETCH_STOP) {
 		tf_policy = ie->target_fetch_policy[iq->depth];
 	}
@@ -2352,6 +2419,13 @@
 			/* wait to get all targets, we want to try em */
 			verbose(VERB_ALGO, "wait for all targets for fallback");
 			qstate->ext_state[id] = module_wait_reply;
+			/* undo qname minimise step because we'll get back here
+			 * to do it again */
+			if(qout_orig && iq->minimise_count > 0) {
+				iq->minimise_count--;
+				iq->qinfo_out.qname = qout_orig;
+				iq->qinfo_out.qname_len = qout_orig_len;
+			}
 			return 0;
 		}
 		/* did we do enough fallback queries already? */
@@ -2372,6 +2446,7 @@
 			iq->num_current_queries++; /* RespState decrements it*/
 			iq->referral_count++; /* make sure we don't loop */
 			iq->sent_count = 0;
+			iq->dp_target_count = 0;
 			iq->state = QUERY_RESP_STATE;
 			return 1;
 		}
@@ -2459,6 +2534,7 @@
 					iq->num_current_queries++; /* RespState decrements it*/
 					iq->referral_count++; /* make sure we don't loop */
 					iq->sent_count = 0;
+					iq->dp_target_count = 0;
 					iq->state = QUERY_RESP_STATE;
 					return 1;
 				}
@@ -2485,6 +2561,13 @@
 				iq->num_current_queries);
 			qstate->ext_state[id] = module_wait_reply;
 		}
+		/* undo qname minimise step because we'll get back here
+		 * to do it again */
+		if(qout_orig && iq->minimise_count > 0) {
+			iq->minimise_count--;
+			iq->qinfo_out.qname = qout_orig;
+			iq->qinfo_out.qname_len = qout_orig_len;
+		}
 		return 0;
 	}
 
@@ -2491,7 +2574,8 @@
 	/* if not forwarding, check ratelimits per delegationpoint name */
 	if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) {
 		if(!infra_ratelimit_inc(qstate->env->infra_cache, iq->dp->name,
-			iq->dp->namelen, *qstate->env->now)) {
+			iq->dp->namelen, *qstate->env->now, &qstate->qinfo,
+			qstate->reply)) {
 			lock_basic_lock(&ie->queries_ratelimit_lock);
 			ie->num_queries_ratelimited++;
 			lock_basic_unlock(&ie->queries_ratelimit_lock);
@@ -2720,8 +2804,15 @@
 			&& !(iq->chase_flags & BIT_RD)) {
 			if(FLAGS_GET_RCODE(iq->response->rep->flags) != 
 				LDNS_RCODE_NOERROR) {
-				if(qstate->env->cfg->qname_minimisation_strict)
-					return final_state(iq);
+				if(qstate->env->cfg->qname_minimisation_strict) {
+					if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
+						LDNS_RCODE_NXDOMAIN) {
+						iter_scrub_nxdomain(iq->response);
+						return final_state(iq);
+					}
+					return error_response(qstate, id,
+						LDNS_RCODE_SERVFAIL);
+				}
 				/* Best effort qname-minimisation. 
 				 * Stop minimising and send full query when
 				 * RCODE is not NOERROR. */
@@ -2738,7 +2829,8 @@
 				/* Make subrequest to validate intermediate
 				 * NXDOMAIN if harden-below-nxdomain is
 				 * enabled. */
-				if(qstate->env->cfg->harden_below_nxdomain) {
+				if(qstate->env->cfg->harden_below_nxdomain &&
+					qstate->env->need_to_validate) {
 					struct module_qstate* subq = NULL;
 					log_query_info(VERB_QUERY,
 						"schedule NXDOMAIN validation:",
@@ -2750,16 +2842,10 @@
 						iq->response->qinfo.qclass,
 						qstate, id, iq,
 						INIT_REQUEST_STATE,
-						FINISHED_STATE, &subq, 1))
+						FINISHED_STATE, &subq, 1, 1))
 						verbose(VERB_ALGO,
 						"could not validate NXDOMAIN "
 						"response");
-					outbound_list_clear(&iq->outlist);
-					iq->num_current_queries = 0;
-					fptr_ok(fptr_whitelist_modenv_detach_subs(
-						qstate->env->detach_subs));
-					(*qstate->env->detach_subs)(qstate);
-					iq->num_target_queries = 0;
 				}
 			}
 			return next_state(iq, QUERYTARGETS_STATE);
@@ -2843,6 +2929,7 @@
 		/* Count this as a referral. */
 		iq->referral_count++;
 		iq->sent_count = 0;
+		iq->dp_target_count = 0;
 		/* see if the next dp is a trust anchor, or a DS was sent
 		 * along, indicating dnssec is expected for next zone */
 		iq->dnssec_expected = iter_indicates_dnssec(qstate->env, 
@@ -2919,6 +3006,7 @@
 		iq->dsns_point = NULL;
 		iq->auth_zone_response = 0;
 		iq->sent_count = 0;
+		iq->dp_target_count = 0;
 		if(iq->minimisation_state != MINIMISE_STATE)
 			/* Only count as query restart when it is not an extra
 			 * query as result of qname minimisation. */
@@ -3111,7 +3199,7 @@
 		if(!generate_sub_request(qstate->qinfo.qname, 
 			qstate->qinfo.qname_len, qstate->qinfo.qtype,
 			qstate->qinfo.qclass, qstate, id, iq,
-			INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
+			INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
 			verbose(VERB_ALGO, "could not generate prime check");
 		}
 		generate_a_aaaa_check(qstate, iq, id);
@@ -3139,6 +3227,7 @@
 processTargetResponse(struct module_qstate* qstate, int id,
 	struct module_qstate* forq)
 {
+	struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
 	struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
 	struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id];
 	struct ub_packed_rrset_key* rrset;
@@ -3176,7 +3265,7 @@
 		log_rrset_key(VERB_ALGO, "add parentside glue to dp", 
 			iq->pside_glue);
 		if(!delegpt_add_rrset(foriq->dp, forq->region, 
-			iq->pside_glue, 1))
+			iq->pside_glue, 1, NULL))
 			log_err("out of memory adding pside glue");
 	}
 
@@ -3187,6 +3276,7 @@
 	 * response type was ANSWER. */
 	rrset = reply_find_answer_rrset(&iq->qchase, qstate->return_msg->rep);
 	if(rrset) {
+		int additions = 0;
 		/* if CNAMEs have been followed - add new NS to delegpt. */
 		/* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */
 		if(!delegpt_find_ns(foriq->dp, rrset->rk.dname, 
@@ -3198,13 +3288,23 @@
 		}
 		/* if dpns->lame then set the address(es) lame too */
 		if(!delegpt_add_rrset(foriq->dp, forq->region, rrset, 
-			dpns->lame))
+			dpns->lame, &additions))
 			log_err("out of memory adding targets");
+		if(!additions) {
+			/* no new addresses, increase the nxns counter, like
+			 * this could be a list of wildcards with no new
+			 * addresses */
+			target_count_increase_nx(foriq, 1);
+		}
 		verbose(VERB_ALGO, "added target response");
 		delegpt_log(VERB_ALGO, foriq->dp);
 	} else {
 		verbose(VERB_ALGO, "iterator TargetResponse failed");
+		delegpt_mark_neg(dpns, qstate->qinfo.qtype);
 		dpns->resolved = 1; /* fail the target */
+		if((dpns->got4 == 2 || !ie->supports_ipv4) &&
+			(dpns->got6 == 2 || !ie->supports_ipv6))
+			target_count_increase_nx(foriq, 1);
 	}
 }
 
@@ -3378,7 +3478,7 @@
 				qstate->qinfo.qname_len, qstate->qinfo.qtype,
 				c, qstate, id, iq, INIT_REQUEST_STATE,
 				FINISHED_STATE, &subq, 
-				(int)!(qstate->query_flags&BIT_CD))) {
+				(int)!(qstate->query_flags&BIT_CD), 0)) {
 				errinf(qstate, "could not generate class ANY"
 					" lookup query");
 				return error_response(qstate, id, 
@@ -3592,7 +3692,7 @@
 	if(event == module_event_noreply || event == module_event_error) {
 		if(event == module_event_noreply && iq->sent_count >= 3 &&
 			qstate->env->cfg->use_caps_bits_for_id &&
-			!iq->caps_fallback) {
+			!iq->caps_fallback && !is_caps_whitelisted(ie, iq)) {
 			/* start fallback */
 			iq->caps_fallback = 1;
 			iq->caps_server = 0;
--- contrib/unbound/iterator/iterator.h.orig
+++ contrib/unbound/iterator/iterator.h
@@ -55,6 +55,11 @@
 
 /** max number of targets spawned for a query and its subqueries */
 #define MAX_TARGET_COUNT	64
+/** max number of target lookups per qstate, per delegation point */
+#define MAX_DP_TARGET_COUNT	16
+/** max number of nxdomains allowed for target lookups for a query and
+ * its subqueries */
+#define MAX_TARGET_NX		5
 /** max number of query restarts. Determines max number of CNAME chain. */
 #define MAX_RESTART_COUNT       8
 /** max number of referrals. Makes sure resolver does not run away */
@@ -83,7 +88,7 @@
 /** how nice is a server without further information, in msec 
  * Equals rtt initial timeout value.
  */
-#define UNKNOWN_SERVER_NICENESS 376
+extern int UNKNOWN_SERVER_NICENESS;
 /** maximum timeout before a host is deemed unsuitable, in msec. 
  * After host_ttl this will be timed out and the host will be tried again. 
  * Equals RTT_MAX_TIMEOUT
@@ -305,9 +310,14 @@
 	int sent_count;
 	
 	/** number of target queries spawned in [1], for this query and its
-	 * subqueries, the malloced-array is shared, [0] refcount. */
+	 * subqueries, the malloced-array is shared, [0] refcount.
+	 * in [2] the number of nxdomains is counted. */
 	int* target_count;
 
+	/** number of target lookups per delegation point. Reset to 0 after
+	 * receiving referral answer. Not shared with subqueries. */
+	int dp_target_count;
+
 	/** if true, already tested for ratelimiting and passed the test */
 	int ratelimit_ok;
 
--- contrib/unbound/libunbound/context.c.orig
+++ contrib/unbound/libunbound/context.c
@@ -55,11 +55,19 @@
 int 
 context_finalize(struct ub_ctx* ctx)
 {
+	int is_rpz = 0;
 	struct config_file* cfg = ctx->env->cfg;
 	verbosity = cfg->verbosity;
-	if(ctx->logfile_override)
+	if(ctx_logfile_overridden && !ctx->logfile_override) {
+		log_file(NULL); /* clear that override */
+		ctx_logfile_overridden = 0;
+	}
+	if(ctx->logfile_override) {
+		ctx_logfile_overridden = 1;
 		log_file(ctx->log_out);
-	else	log_init(cfg->logfile, cfg->use_syslog, NULL);
+	} else {
+		log_init(cfg->logfile, cfg->use_syslog, NULL);
+	}
 	config_apply(cfg);
 	if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
 		return UB_INITFAIL;
@@ -69,7 +77,7 @@
 		return UB_NOMEM;
 	if(!local_zones_apply_cfg(ctx->local_zones, cfg))
 		return UB_INITFAIL;
-	if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1))
+	if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz))
 		return UB_INITFAIL;
 	if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
 		cfg->msg_cache_slabs)) {
--- contrib/unbound/libunbound/context.h.orig
+++ contrib/unbound/libunbound/context.h
@@ -52,6 +52,9 @@
 struct sldns_buffer;
 struct ub_event_base;
 
+/** store that the logfile has a debug override */
+extern int ctx_logfile_overridden;
+
 /**
  * The context structure
  *
@@ -116,6 +119,9 @@
 
 	/** event base for event oriented interface */
 	struct ub_event_base* event_base;
+	/** true if the event_base is a pluggable base that is malloced
+	 * with a user event base inside, if so, clean up the pluggable alloc*/
+	int event_base_malloced;
 	/** libworker for event based interface */
 	struct libworker* event_worker;
 
--- contrib/unbound/libunbound/libunbound.c.orig
+++ contrib/unbound/libunbound/libunbound.c
@@ -79,11 +79,13 @@
 #include <iphlpapi.h>
 #endif /* UB_ON_WINDOWS */
 
+/** store that the logfile has a debug override */
+int ctx_logfile_overridden = 0;
+
 /** create context functionality, but no pipes */
 static struct ub_ctx* ub_ctx_create_nopipe(void)
 {
 	struct ub_ctx* ctx;
-	unsigned int seed;
 #ifdef USE_WINSOCK
 	int r;
 	WSADATA wsa_data;
@@ -90,7 +92,8 @@
 #endif
 	
 	checklock_start();
-	log_init(NULL, 0, NULL); /* logs to stderr */
+	if(!ctx_logfile_overridden)
+		log_init(NULL, 0, NULL); /* logs to stderr */
 	log_ident_set("libunbound");
 #ifdef USE_WINSOCK
 	if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
@@ -99,7 +102,7 @@
 		return NULL;
 	}
 #endif
-	verbosity = 0; /* errors only */
+	verbosity = NO_VERBOSE; /* errors only */
 	checklock_start();
 	ctx = (struct ub_ctx*)calloc(1, sizeof(*ctx));
 	if(!ctx) {
@@ -107,15 +110,12 @@
 		return NULL;
 	}
 	alloc_init(&ctx->superalloc, NULL, 0);
-	seed = (unsigned int)time(NULL) ^ (unsigned int)getpid();
-	if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) {
-		explicit_bzero(&seed, sizeof(seed));
+	if(!(ctx->seed_rnd = ub_initstate(NULL))) {
 		ub_randfree(ctx->seed_rnd);
 		free(ctx);
 		errno = ENOMEM;
 		return NULL;
 	}
-	explicit_bzero(&seed, sizeof(seed));
 	lock_basic_init(&ctx->qqpipe_lock);
 	lock_basic_init(&ctx->rrpipe_lock);
 	lock_basic_init(&ctx->cfglock);
@@ -222,6 +222,7 @@
 		ub_ctx_delete(ctx);
 		return NULL;
 	}
+	ctx->event_base_malloced = 1;
 	return ctx;
 }
 	
@@ -328,6 +329,12 @@
 	ub_randfree(ctx->seed_rnd);
 	alloc_clear(&ctx->superalloc);
 	traverse_postorder(&ctx->queries, delq, NULL);
+	if(ctx_logfile_overridden) {
+		log_file(NULL);
+		ctx_logfile_overridden = 0;
+	}
+	if(ctx->event_base_malloced)
+		free(ctx->event_base);
 	free(ctx);
 #ifdef USE_WINSOCK
 	WSACleanup();
@@ -469,6 +476,7 @@
 {
 	lock_basic_lock(&ctx->cfglock);
 	log_file((FILE*)out);
+	ctx_logfile_overridden = 1;
 	ctx->logfile_override = 1;
 	ctx->log_out = out;
 	lock_basic_unlock(&ctx->cfglock);
@@ -724,7 +732,7 @@
 		*async_id = 0;
 	lock_basic_lock(&ctx->cfglock);
 	if(!ctx->finalized) {
-		int r = context_finalize(ctx);
+		r = context_finalize(ctx);
 		if(r) {
 			lock_basic_unlock(&ctx->cfglock);
 			return r;
@@ -966,6 +974,19 @@
 	return UB_NOERROR;
 }
 
+int ub_ctx_set_tls(struct ub_ctx* ctx, int tls)
+{
+	lock_basic_lock(&ctx->cfglock);
+	if(ctx->finalized) {
+		lock_basic_unlock(&ctx->cfglock);
+		errno=EINVAL;
+		return UB_AFTERFINAL;
+	}
+	ctx->env->cfg->ssl_upstream = tls;
+	lock_basic_unlock(&ctx->cfglock);
+	return UB_NOERROR;
+}
+
 int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
 	int isprime)
 {
@@ -1137,7 +1158,7 @@
 ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
 {
 	FILE* in;
-	char buf[1024], ldata[1024];
+	char buf[1024], ldata[2048];
 	char* parse, *addr, *name, *ins;
 	lock_basic_lock(&ctx->cfglock);
 	if(ctx->finalized) {
--- contrib/unbound/libunbound/libworker.c.orig
+++ contrib/unbound/libunbound/libworker.c
@@ -122,7 +122,6 @@
 static struct libworker*
 libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
 {
-	unsigned int seed;
 	struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
 	struct config_file* cfg = ctx->env->cfg;
 	int* ports;
@@ -177,17 +176,13 @@
 	}
 	w->env->worker = (struct worker*)w;
 	w->env->probe_timer = NULL;
-	seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
-		(((unsigned int)w->thread_num)<<17);
-	seed ^= (unsigned int)w->env->alloc->next_id;
 	if(!w->is_bg || w->is_bg_thread) {
 		lock_basic_lock(&ctx->cfglock);
 	}
-	if(!(w->env->rnd = ub_initstate(seed, ctx->seed_rnd))) {
+	if(!(w->env->rnd = ub_initstate(ctx->seed_rnd))) {
 		if(!w->is_bg || w->is_bg_thread) {
 			lock_basic_unlock(&ctx->cfglock);
 		}
-		explicit_bzero(&seed, sizeof(seed));
 		libworker_delete(w);
 		return NULL;
 	}
@@ -207,7 +202,6 @@
 			hash_set_raninit((uint32_t)ub_random(w->env->rnd));
 		}
 	}
-	explicit_bzero(&seed, sizeof(seed));
 
 	if(eb)
 		w->base = comm_base_create_event(eb);
@@ -222,11 +216,10 @@
 	}
 	numports = cfg_condense_ports(cfg, &ports);
 	if(numports == 0) {
-		int locked = !w->is_bg || w->is_bg_thread;
-		libworker_delete(w);
-		if(locked) {
+		if(!w->is_bg || w->is_bg_thread) {
 			lock_basic_unlock(&ctx->cfglock);
 		}
+		libworker_delete(w);
 		return NULL;
 	}
 	w->back = outside_network_create(w->base, cfg->msg_buffer_size,
@@ -533,7 +526,7 @@
 	}
 
 	q->res->rcode = LDNS_RCODE_SERVFAIL;
-	q->msg_security = 0;
+	q->msg_security = sec_status_unchecked;
 	q->msg = memdup(sldns_buffer_begin(buf), sldns_buffer_limit(buf));
 	q->msg_len = sldns_buffer_limit(buf);
 	if(!q->msg) {
@@ -568,7 +561,6 @@
 	if(!qinfo->qname) {
 		return 0;
 	}
-	qinfo->local_alias = NULL;
 	edns->edns_present = 1;
 	edns->ext_rcode = 0;
 	edns->edns_version = 0;
@@ -657,8 +649,8 @@
 			sec = 1;
 		else if(s == sec_status_secure)
 			sec = 2;
-		(*cb)(cb_arg, rcode, (void*)sldns_buffer_begin(buf),
-			(int)sldns_buffer_limit(buf), sec, why_bogus, was_ratelimited);
+		(*cb)(cb_arg, rcode, (buf?(void*)sldns_buffer_begin(buf):NULL),
+			(buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus, was_ratelimited);
 	}
 }
 
--- contrib/unbound/libunbound/ubsyms.def.orig
+++ contrib/unbound/libunbound/ubsyms.def
@@ -20,6 +20,7 @@
 ub_ctx_set_fwd
 ub_ctx_set_option
 ub_ctx_set_stub
+ub_ctx_set_tls
 ub_ctx_trustedkeys
 ub_ctx_zone_add
 ub_ctx_zone_remove
--- contrib/unbound/libunbound/unbound.h.orig
+++ contrib/unbound/libunbound/unbound.h
@@ -204,8 +204,9 @@
 	char* why_bogus;
 
 	/**
-	 * If the query or one of its subqueries was ratelimited. Useful if
-	 * ratelimiting is enabled and answer is SERVFAIL.
+	 * If the query or one of its subqueries was ratelimited.  Useful if
+	 * ratelimiting is enabled and answer to the client is SERVFAIL as a
+	 * result.
 	 */
 	int was_ratelimited;
 
@@ -310,6 +311,17 @@
 int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr);
 
 /**
+ * Use DNS over TLS to send queries to machines set with ub_ctx_set_fwd().
+ *
+ * @param ctx: context.
+ *	At this time it is only possible to set configuration before the
+ *	first resolve is done.
+ * @param tls: enable or disable DNS over TLS
+ * @return 0 if OK, else error.
+ */
+int ub_ctx_set_tls(struct ub_ctx* ctx, int tls);
+
+/**
  * Add a stub zone, with given address to send to.  This is for custom
  * root hints or pointing to a local authoritative dns server.
  * For dns resolvers and the 'DHCP DNS' ip address, use ub_ctx_set_fwd.
@@ -643,6 +655,8 @@
 #define UB_STATS_OPCODE_NUM 16
 /** number of histogram buckets */
 #define UB_STATS_BUCKET_NUM 40
+/** number of RPZ actions */
+#define UB_STATS_RPZ_ACTION_NUM 10
 
 /** per worker statistics. */
 struct ub_server_stats {
@@ -722,8 +736,8 @@
 	long long unwanted_queries;
 	/** usage of tcp accept list */
 	long long tcp_accept_usage;
-	/** answers served from expired cache */
-	long long zero_ttl_responses;
+	/** expired answers served from cache */
+	long long ans_expired;
 	/** histogram data exported to array 
 	 * if the array is the same size, no data is lost, and
 	 * if all histograms are same size (is so by default) then
@@ -770,6 +784,12 @@
 	/** number of queries answered from edns-subnet specific data, and
 	 * the answer was from the edns-subnet cache. */
 	long long num_query_subnet_cache;
+	/** number of bytes in the stream wait buffers */
+	long long mem_stream_wait;
+	/** number of TLS connection resume */
+	long long qtls_resume;
+	/** RPZ action stats */
+	long long rpz_action[UB_STATS_RPZ_ACTION_NUM];
 };
 
 /** 
--- contrib/unbound/ltmain.sh.orig
+++ contrib/unbound/ltmain.sh
@@ -2124,7 +2124,7 @@
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
+    func_fatal_error ${1+"$@"} \
       "See the $PACKAGE documentation for more information." \
       "Fatal configuration error."
 }
@@ -7272,10 +7272,12 @@
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+      -specs=*)
         func_quote_for_eval "$arg"
 	arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
--- contrib/unbound/respip/respip.c.orig
+++ contrib/unbound/respip/respip.c
@@ -12,6 +12,7 @@
 #include "config.h"
 
 #include "services/localzone.h"
+#include "services/authzone.h"
 #include "services/cache/dns.h"
 #include "sldns/str2wire.h"
 #include "util/config_file.h"
@@ -25,31 +26,7 @@
 #include "services/view.h"
 #include "sldns/rrdef.h"
 
-/**
- * Conceptual set of IP addresses for response AAAA or A records that should
- * trigger special actions.
- */
-struct respip_set {
-	struct regional* region;
-	struct rbtree_type ip_tree;
-	char* const* tagname;	/* shallow copy of tag names, for logging */
-	int num_tags;		/* number of tagname entries */
-};
 
-/** An address span with response control information */
-struct resp_addr {
-	/** node in address tree */
-	struct addr_tree_node node;
-	/** tag bitlist */
-	uint8_t* taglist;
-	/** length of the taglist (in bytes) */
-	size_t taglen;
-	/** action for this address span */
-	enum respip_action action;
-        /** "local data" for this node */
-	struct ub_packed_rrset_key* data;
-};
-
 /** Subset of resp_addr.node, used for inform-variant logging */
 struct respip_addr_info {
 	struct sockaddr_storage addr;
@@ -88,14 +65,28 @@
 		return NULL;
 	}
 	addr_tree_init(&set->ip_tree);
+	lock_rw_init(&set->lock);
 	return set;
 }
 
+/** helper traverse to delete resp_addr nodes */
+static void
+resp_addr_del(rbnode_type* n, void* ATTR_UNUSED(arg))
+{
+	struct resp_addr* r = (struct resp_addr*)n->key;
+	lock_rw_destroy(&r->lock);
+#ifdef THREADS_DISABLED
+	(void)r;
+#endif
+}
+
 void
 respip_set_delete(struct respip_set* set)
 {
 	if(!set)
 		return;
+	lock_rw_destroy(&set->lock);
+	traverse_postorder(&set->ip_tree, resp_addr_del, NULL);
 	regional_destroy(set->region);
 	free(set);
 }
@@ -108,21 +99,12 @@
 	return &set->ip_tree;
 }
 
-/** returns the node in the address tree for the specified netblock string;
- * non-existent node will be created if 'create' is true */
-static struct resp_addr*
-respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
+struct resp_addr*
+respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
+		socklen_t addrlen, int net, int create, const char* ipstr)
 {
 	struct resp_addr* node;
-	struct sockaddr_storage addr;
-	int net;
-	socklen_t addrlen;
-
-	if(!netblockstrtoaddr(ipstr, 0, &addr, &addrlen, &net)) {
-		log_err("cannot parse netblock: '%s'", ipstr);
-		return NULL;
-	}
-	node = (struct resp_addr*)addr_tree_find(&set->ip_tree, &addr, addrlen, net);
+	node = (struct resp_addr*)addr_tree_find(&set->ip_tree, addr, addrlen, net);
 	if(!node && create) {
 		node = regional_alloc_zero(set->region, sizeof(*node));
 		if(!node) {
@@ -129,8 +111,9 @@
 			log_err("out of memory");
 			return NULL;
 		}
+		lock_rw_init(&node->lock);
 		node->action = respip_none;
-		if(!addr_tree_insert(&set->ip_tree, &node->node, &addr,
+		if(!addr_tree_insert(&set->ip_tree, &node->node, addr,
 			addrlen, net)) {
 			/* We know we didn't find it, so this should be
 			 * impossible. */
@@ -140,6 +123,37 @@
 	return node;
 }
 
+void
+respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node)
+{
+	struct resp_addr* prev;
+	prev = (struct resp_addr*)rbtree_previous((struct rbnode_type*)node);	
+	lock_rw_destroy(&node->lock);
+	rbtree_delete(&set->ip_tree, node);
+	/* no free'ing, all allocated in region */
+	if(!prev)
+		addr_tree_init_parents((rbtree_type*)set);
+	else
+		addr_tree_init_parents_node(&prev->node);
+}
+
+/** returns the node in the address tree for the specified netblock string;
+ * non-existent node will be created if 'create' is true */
+static struct resp_addr*
+respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
+{
+	struct sockaddr_storage addr;
+	int net;
+	socklen_t addrlen;
+
+	if(!netblockstrtoaddr(ipstr, 0, &addr, &addrlen, &net)) {
+		log_err("cannot parse netblock: '%s'", ipstr);
+		return NULL;
+	}
+	return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create,
+		ipstr);
+}
+
 static int
 respip_tag_cfg(struct respip_set* set, const char* ipstr,
 	const uint8_t* taglist, size_t taglen)
@@ -183,6 +197,8 @@
                 action = respip_inform;
         else if(strcmp(actnstr, "inform_deny") == 0)
                 action = respip_inform_deny;
+        else if(strcmp(actnstr, "inform_redirect") == 0)
+                action = respip_inform_redirect;
         else if(strcmp(actnstr, "always_transparent") == 0)
                 action = respip_always_transparent;
         else if(strcmp(actnstr, "always_refuse") == 0)
@@ -189,6 +205,10 @@
                 action = respip_always_refuse;
         else if(strcmp(actnstr, "always_nxdomain") == 0)
                 action = respip_always_nxdomain;
+        else if(strcmp(actnstr, "always_nodata") == 0)
+                action = respip_always_nodata;
+        else if(strcmp(actnstr, "always_deny") == 0)
+                action = respip_always_deny;
         else {
                 log_err("unknown response-ip action %s", actnstr);
                 return 0;
@@ -230,8 +250,43 @@
 }
 
 /** enter local data as resource records into a response-ip node */
+
+int
+respip_enter_rr(struct regional* region, struct resp_addr* raddr,
+	uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
+	size_t rdata_len, const char* rrstr, const char* netblockstr)
+{
+	struct packed_rrset_data* pd;
+	struct sockaddr* sa;
+	sa = (struct sockaddr*)&raddr->node.addr;
+	if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
+		log_err("CNAME response-ip data (%s) can not co-exist with other "
+			"response-ip data for netblock %s", rrstr, netblockstr);
+		return 0;
+	} else if (raddr->data &&
+		raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
+		log_err("response-ip data (%s) can not be added; CNAME response-ip "
+			"data already in place for netblock %s", rrstr, netblockstr);
+		return 0;
+	} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
+		((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
+		(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
+		log_err("response-ip data %s record type does not correspond "
+			"to netblock %s address family", rrstr, netblockstr);
+		return 0;
+	}
+
+	if(!raddr->data) {
+		raddr->data = new_rrset(region, rrtype, rrclass);
+		if(!raddr->data)
+			return 0;
+	}
+	pd = raddr->data->entry.data;
+	return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
+}
+
 static int
-respip_enter_rr(struct regional* region, struct resp_addr* raddr,
+respip_enter_rrstr(struct regional* region, struct resp_addr* raddr,
 		const char* rrstr, const char* netblock)
 {
 	uint8_t* nm;
@@ -242,10 +297,9 @@
 	size_t rdata_len = 0;
 	char buf[65536];
 	char bufshort[64];
-	struct packed_rrset_data* pd;
-	struct sockaddr* sa;
 	int ret;
-	if(raddr->action != respip_redirect) {
+	if(raddr->action != respip_redirect
+		&& raddr->action != respip_inform_redirect) {
 		log_err("cannot parse response-ip-data %s: response-ip "
 			"action for %s is not redirect", rrstr, netblock);
 		return 0;
@@ -262,31 +316,8 @@
 		return 0;
 	}
 	free(nm);
-	sa = (struct sockaddr*)&raddr->node.addr;
-	if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
-		log_err("CNAME response-ip data (%s) can not co-exist with other "
-			"response-ip data for netblock %s", rrstr, netblock);
-		return 0;
-	} else if (raddr->data &&
-		raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
-		log_err("response-ip data (%s) can not be added; CNAME response-ip "
-			"data already in place for netblock %s", rrstr, netblock);
-		return 0;
-	} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
-		((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
-		(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
-		log_err("response-ip data %s record type does not correspond "
-			"to netblock %s address family", rrstr, netblock);
-		return 0;
-	}
-
-	if(!raddr->data) {
-		raddr->data = new_rrset(region, rrtype, rrclass);
-		if(!raddr->data)
-			return 0;
-	}
-	pd = raddr->data->entry.data;
-	return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
+	return respip_enter_rr(region, raddr, rrtype, rrclass, ttl, rdata,
+		rdata_len, rrstr, netblock);
 }
 
 static int
@@ -300,7 +331,7 @@
 			"response-ip node for %s not found", rrstr, ipstr);
 		return 0;
 	}
-	return respip_enter_rr(set->region, node, rrstr, ipstr);
+	return respip_enter_rrstr(set->region, node, rrstr, ipstr);
 }
 
 static int
@@ -358,6 +389,7 @@
 		free(pd);
 		pd = np;
 	}
+	addr_tree_init_parents(&set->ip_tree);
 
 	return 1;
 }
@@ -475,10 +507,16 @@
 	if(!ck->rk.dname)
 		return NULL;
 
+	if((unsigned)data->count >= 0xffff00U)
+		return NULL; /* guard against integer overflow in dsize */
 	dsize = sizeof(struct packed_rrset_data) + data->count *
 		(sizeof(size_t)+sizeof(uint8_t*)+sizeof(time_t));
-	for(i=0; i<data->count; i++)
+	for(i=0; i<data->count; i++) {
+		if((unsigned)dsize >= 0x0fffffffU ||
+			(unsigned)data->rr_len[i] >= 0x0fffffffU)
+			return NULL; /* guard against integer overflow */
 		dsize += data->rr_len[i];
+	}
 	d = regional_alloc(region, dsize);
 	if(!d)
 		return NULL;
@@ -554,9 +592,10 @@
  * rep->rrsets for the RRset that contains the matching IP address record
  * (the index is normally 0, but can be larger than that if this is a CNAME
  * chain or type-ANY response).
+ * Returns resp_addr holding read lock.
  */
-static const struct resp_addr*
-respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree,
+static struct resp_addr*
+respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
 	size_t* rrset_id)
 {
 	size_t i;
@@ -564,6 +603,7 @@
 	struct sockaddr_storage ss;
 	socklen_t addrlen;
 
+	lock_rw_rdlock(&rs->lock);
 	for(i=0; i<rep->an_numrrsets; i++) {
 		size_t j;
 		const struct packed_rrset_data* rd;
@@ -575,15 +615,17 @@
 		for(j = 0; j < rd->count; j++) {
 			if(!rdata2sockaddr(rd, rtype, j, &ss, &addrlen))
 				continue;
-			ra = (struct resp_addr*)addr_tree_lookup(iptree, &ss,
-				addrlen);
+			ra = (struct resp_addr*)addr_tree_lookup(&rs->ip_tree,
+				&ss, addrlen);
 			if(ra) {
 				*rrset_id = i;
+				lock_rw_rdlock(&ra->lock);
+				lock_rw_unlock(&rs->lock);
 				return ra;
 			}
 		}
 	}
-
+	lock_rw_unlock(&rs->lock);
 	return NULL;
 }
 
@@ -632,8 +674,8 @@
  * Note that this function distinguishes error conditions from "success but
  * not overridden".  This is because we want to avoid accidentally applying
  * the "no data" action in case of error.
- * @param raddr: address span that requires an action
  * @param action: action to apply
+ * @param data: RRset to use for override
  * @param qtype: original query type
  * @param rep: original reply message
  * @param rrset_id: the rrset ID in 'rep' to which the action should apply
@@ -648,7 +690,8 @@
  * @return 1 if overridden, 0 if not overridden, -1 on error.
  */
 static int
-respip_data_answer(const struct resp_addr* raddr, enum respip_action action,
+respip_data_answer(enum respip_action action,
+	struct ub_packed_rrset_key* data,
 	uint16_t qtype, const struct reply_info* rep,
 	size_t rrset_id, struct reply_info** new_repp, int tag,
 	struct config_strlist** tag_datas, size_t tag_datas_size,
@@ -655,7 +698,7 @@
 	char* const* tagname, int num_tags,
 	struct ub_packed_rrset_key** redirect_rrsetp, struct regional* region)
 {
-	struct ub_packed_rrset_key* rp = raddr->data;
+	struct ub_packed_rrset_key* rp = data;
 	struct reply_info* new_rep;
 	*redirect_rrsetp = NULL;
 
@@ -693,7 +736,7 @@
 	 * to replace the rrset's dname.  Note that, unlike local data, we
 	 * rename the dname for other actions than redirect.  This is because
 	 * response-ip-data isn't associated to any specific name. */
-	if(rp == raddr->data) {
+	if(rp == data) {
 		rp = copy_rrset(rp, region);
 		if(!rp)
 			return -1;
@@ -750,7 +793,9 @@
 		*new_repp = new_rep;
 		return 1;
 	} else if(action == respip_static || action == respip_redirect ||
-		action == respip_always_nxdomain) {
+		action == respip_always_nxdomain ||
+		action == respip_always_nodata ||
+		action == respip_inform_redirect) {
 		/* Since we don't know about other types of the owner name,
 		 * we generally return NOERROR/NODATA unless an NXDOMAIN action
 		 * is explicitly specified. */
@@ -783,16 +828,22 @@
 	enum respip_action action, const struct resp_addr* raddr,
 	const struct ub_packed_rrset_key* ATTR_UNUSED(rrset),
 	int ATTR_UNUSED(tag), const struct respip_set* ATTR_UNUSED(ipset),
-	int ATTR_UNUSED(action_only), struct regional* region)
+	int ATTR_UNUSED(action_only), struct regional* region, int rpz_used,
+	int rpz_log, char* log_name, int rpz_cname_override)
 {
 	if(action == respip_none || !raddr)
 		return 1;
 	actinfo->action = action;
+	actinfo->rpz_used = rpz_used;
+	actinfo->rpz_log = rpz_log;
+	actinfo->log_name = log_name;
+	actinfo->rpz_cname_override = rpz_cname_override;
 
 	/* for inform variants, make a copy of the matched address block for
 	 * later logging.  We make a copy to proactively avoid disruption if
 	 *  and when we allow a dynamic update to the respip tree. */
-	if(action == respip_inform || action == respip_inform_deny) {
+	if(action == respip_inform || action == respip_inform_deny ||
+		rpz_used) {
 		struct respip_addr_info* a =
 			regional_alloc_zero(region, sizeof(*a));
 		if(!a) {
@@ -808,12 +859,39 @@
 	return 1;
 }
 
+static int
+respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
+	enum respip_action* action,
+	struct ub_packed_rrset_key** data, int* rpz_log, char** log_name,
+	int* rpz_cname_override, struct regional* region, int* is_rpz)
+{
+	if(r->action_override == RPZ_DISABLED_ACTION) {
+		*is_rpz = 0;
+		return 1;
+	}
+	else if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
+		*action = raddr->action;
+	else
+		*action = rpz_action_to_respip_action(r->action_override);
+	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION &&
+		r->cname_override) {
+		*data = r->cname_override;
+		*rpz_cname_override = 1;
+	}
+	*rpz_log = r->log;
+	if(r->log_name)
+		if(!(*log_name = regional_strdup(region, r->log_name)))
+			return 0;
+	*is_rpz = 1;
+	return 1;
+}
+
 int
 respip_rewrite_reply(const struct query_info* qinfo,
 	const struct respip_client_info* cinfo, const struct reply_info* rep,
 	struct reply_info** new_repp, struct respip_action_info* actinfo,
 	struct ub_packed_rrset_key** alias_rrset, int search_only,
-	struct regional* region)
+	struct regional* region, struct auth_zones* az)
 {
 	const uint8_t* ctaglist;
 	size_t ctaglen;
@@ -826,9 +904,15 @@
 	size_t rrset_id = 0;
 	enum respip_action action = respip_none;
 	int tag = -1;
-	const struct resp_addr* raddr = NULL;
+	struct resp_addr* raddr = NULL;
 	int ret = 1;
 	struct ub_packed_rrset_key* redirect_rrset = NULL;
+	struct rpz* r;
+	struct ub_packed_rrset_key* data = NULL;
+	int rpz_used = 0;
+	int rpz_log = 0;
+	int rpz_cname_override = 0;
+	char* log_name = NULL;
 
 	if(!cinfo)
 		goto done;
@@ -841,6 +925,8 @@
 	view = cinfo->view;
 	ipset = cinfo->respip_set;
 
+	log_assert(ipset);
+
 	/** Try to use response-ip config from the view first; use
 	  * global response-ip config if we don't have the view or we don't
 	  * have the matching per-view config (and the view allows the use
@@ -855,7 +941,7 @@
 		lock_rw_rdlock(&view->lock);
 		if(view->respip_set) {
 			if((raddr = respip_addr_lookup(rep,
-				&view->respip_set->ip_tree, &rrset_id))) {
+				view->respip_set, &rrset_id))) {
 				/** for per-view respip directives the action
 				 * can only be direct (i.e. not tag-based) */
 				action = raddr->action;
@@ -864,7 +950,7 @@
 		if(!raddr && !view->isfirst)
 			goto done;
 	}
-	if(!raddr && ipset && (raddr = respip_addr_lookup(rep, &ipset->ip_tree,
+	if(!raddr && (raddr = respip_addr_lookup(rep, ipset,
 		&rrset_id))) {
 		action = (enum respip_action)local_data_find_tag_action(
 			raddr->taglist, raddr->taglen, ctaglist, ctaglen,
@@ -872,6 +958,29 @@
 			(enum localzone_type)raddr->action, &tag,
 			ipset->tagname, ipset->num_tags);
 	}
+	lock_rw_rdlock(&az->rpz_lock);
+	for(r = az->rpz_first; r && !raddr; r = r->next) {
+		if(!r->taglist || taglist_intersect(r->taglist, 
+			r->taglistlen, ctaglist, ctaglen)) {
+			if((raddr = respip_addr_lookup(rep,
+				r->respip_set, &rrset_id))) {
+				if(!respip_use_rpz(raddr, r, &action, &data,
+					&rpz_log, &log_name, &rpz_cname_override,
+					region, &rpz_used)) {
+					log_err("out of memory");
+					lock_rw_unlock(&raddr->lock);
+					lock_rw_unlock(&az->rpz_lock);
+					return 0;
+				}
+				if(!rpz_used) {
+					lock_rw_unlock(&raddr->lock);
+					raddr = NULL;
+					actinfo->rpz_disabled++;
+				}
+			}
+		}	
+	}
+	lock_rw_unlock(&az->rpz_lock);
 	if(raddr && !search_only) {
 		int result = 0;
 
@@ -880,10 +989,13 @@
 		if(action != respip_always_refuse
 			&& action != respip_always_transparent
 			&& action != respip_always_nxdomain
-			&& (result = respip_data_answer(raddr, action,
-			qinfo->qtype, rep, rrset_id, new_repp, tag, tag_datas,
-			tag_datas_size, ipset->tagname, ipset->num_tags,
-			&redirect_rrset, region)) < 0) {
+			&& action != respip_always_nodata
+			&& action != respip_always_deny
+			&& (result = respip_data_answer(action,
+			(data) ? data : raddr->data, qinfo->qtype, rep,
+			rrset_id, new_repp, tag, tag_datas, tag_datas_size,
+			ipset->tagname, ipset->num_tags, &redirect_rrset,
+			region)) < 0) {
 			ret = 0;
 			goto done;
 		}
@@ -914,8 +1026,12 @@
 			*alias_rrset = redirect_rrset;
 		/* on success, populate respip result structure */
 		ret = populate_action_info(actinfo, action, raddr,
-			redirect_rrset, tag, ipset, search_only, region);
+			redirect_rrset, tag, ipset, search_only, region,
+				rpz_used, rpz_log, log_name, rpz_cname_override);
 	}
+	if(raddr) {
+		lock_rw_unlock(&raddr->lock);
+	}
 	return ret;
 }
 
@@ -970,14 +1086,15 @@
 			qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA ||
 			qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) &&
 			qstate->return_msg && qstate->return_msg->rep) {
-			struct respip_action_info actinfo = {respip_none, NULL};
 			struct reply_info* new_rep = qstate->return_msg->rep;
 			struct ub_packed_rrset_key* alias_rrset = NULL;
+			struct respip_action_info actinfo = {0};
+			actinfo.action = respip_none;
 
 			if(!respip_rewrite_reply(&qstate->qinfo,
 				qstate->client_info, qstate->return_msg->rep,
 				&new_rep, &actinfo, &alias_rrset, 0,
-				qstate->region)) {
+				qstate->region, qstate->env->auth_zones)) {
 				goto servfail;
 			}
 			if(actinfo.action != respip_none) {
@@ -993,9 +1110,10 @@
 			} else {
 				qstate->respip_action_info = NULL;
 			}
-			if (new_rep == qstate->return_msg->rep &&
+			if (actinfo.action == respip_always_deny ||
+				(new_rep == qstate->return_msg->rep &&
 				(actinfo.action == respip_deny ||
-				actinfo.action == respip_inform_deny)) {
+				actinfo.action == respip_inform_deny))) {
 				/* for deny-variant actions (unless response-ip
 				 * data is applied), mark the query state so
 				 * the response will be dropped for all
@@ -1023,7 +1141,8 @@
 respip_merge_cname(struct reply_info* base_rep,
 	const struct query_info* qinfo, const struct reply_info* tgt_rep,
 	const struct respip_client_info* cinfo, int must_validate,
-	struct reply_info** new_repp, struct regional* region)
+	struct reply_info** new_repp, struct regional* region,
+	struct auth_zones* az)
 {
 	struct reply_info* new_rep;
 	struct reply_info* tmp_rep = NULL; /* just a placeholder */
@@ -1030,7 +1149,8 @@
 	struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */
 	uint16_t tgt_rcode;
 	size_t i, j;
-	struct respip_action_info actinfo = {respip_none, NULL};
+	struct respip_action_info actinfo = {0};
+	actinfo.action = respip_none;
 
 	/* If the query for the CNAME target would result in an unusual rcode,
 	 * we generally translate it as a failure for the base query
@@ -1049,7 +1169,7 @@
 
 	/* see if the target reply would be subject to a response-ip action. */
 	if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo,
-		&alias_rrset, 1, region))
+		&alias_rrset, 1, region, az))
 		return 0;
 	if(actinfo.action != respip_none) {
 		log_info("CNAME target of redirect response-ip action would "
@@ -1101,7 +1221,8 @@
 
 	if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo,
 		qstate->return_msg->rep, super->client_info,
-		super->env->need_to_validate, &new_rep, super->region))
+		super->env->need_to_validate, &new_rep, super->region,
+		qstate->env->auth_zones))
 		goto fail;
 	super->return_msg->rep = new_rep;
 	return;
@@ -1160,12 +1281,15 @@
 }
 
 void
-respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
+respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
 	uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
 	struct comm_reply* repinfo)
 {
 	char srcip[128], respip[128], txt[512];
 	unsigned port;
+	struct respip_addr_info* respip_addr = respip_actinfo->addrinfo;
+	size_t txtlen = 0;
+	const char* actionstr = NULL;
 
 	if(local_alias)
 		qname = local_alias->rrset->rk.dname;
@@ -1175,7 +1299,23 @@
 	addr_to_str(&repinfo->addr, repinfo->addrlen, srcip, sizeof(srcip));
 	addr_to_str(&respip_addr->addr, respip_addr->addrlen,
 		respip, sizeof(respip));
-	snprintf(txt, sizeof(txt), "%s/%d inform %s@%u", respip,
-		respip_addr->net, srcip, port);
-	log_nametypeclass(0, txt, qname, qtype, qclass);
+	if(respip_actinfo->rpz_log) {
+		txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, "%s",
+			"RPZ applied ");
+		if(respip_actinfo->rpz_cname_override)
+			actionstr = rpz_action_to_string(
+				RPZ_CNAME_OVERRIDE_ACTION);
+		else
+			actionstr = rpz_action_to_string(
+				respip_action_to_rpz_action(
+					respip_actinfo->action));
+	}
+	if(respip_actinfo->log_name) {
+		txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen,
+			"[%s] ", respip_actinfo->log_name);
+	}
+	snprintf(txt+txtlen, sizeof(txt)-txtlen,
+		"%s/%d %s %s@%u", respip, respip_addr->net,
+		(actionstr) ? actionstr : "inform", srcip, port);
+	log_nametypeclass(NO_VERBOSE, txt, qname, qtype, qclass);
 }
--- contrib/unbound/respip/respip.h.orig
+++ contrib/unbound/respip/respip.h
@@ -14,23 +14,42 @@
 
 #include "util/module.h"
 #include "services/localzone.h"
+#include "util/locks.h"
 
 /**
- * Set of response IP addresses with associated actions and tags. 
- * Forward declaration only here.  Actual definition is hidden within the
- * module.
+ * Conceptual set of IP addresses for response AAAA or A records that should
+ * trigger special actions.
  */
-struct respip_set;
+struct respip_set {
+	struct regional* region;
+	struct rbtree_type ip_tree;
+	lock_rw_type lock;	/* lock on the respip tree */
+	char* const* tagname;	/* shallow copy of tag names, for logging */
+	int num_tags;		/* number of tagname entries */
+};
 
-/**
- * Forward declaration for the structure that represents a node in the
- * respip_set address tree
- */
-struct resp_addr;
 
+/** An address span with response control information */
+struct resp_addr {
+	/** node in address tree */
+	struct addr_tree_node node;
+	/** lock on the node item */
+	lock_rw_type lock;
+	/** tag bitlist */
+	uint8_t* taglist;
+	/** length of the taglist (in bytes) */
+	size_t taglen;
+	/** action for this address span */
+	enum respip_action action;
+        /** "local data" for this node */
+	struct ub_packed_rrset_key* data;
+};
+
+
 /**
  * Forward declaration for the structure that represents a tree of view data.
  */
+
 struct views;
 
 struct respip_addr_info;
@@ -60,6 +79,11 @@
  */
 struct respip_action_info {
 	enum respip_action action;
+	int rpz_used;
+	int rpz_log;
+	int rpz_disabled;
+	char* log_name;
+	int rpz_cname_override;
 	struct respip_addr_info* addrinfo; /* set only for inform variants */
 };
 
@@ -124,12 +148,14 @@
  * @param new_repp: pointer placeholder for the merged reply.  will be intact
  *   on error.
  * @param region: allocator to build *new_repp.
+ * @param az: auth zones containing RPZ information.
  * @return 1 on success, 0 on error.
  */
 int respip_merge_cname(struct reply_info* base_rep,
 	const struct query_info* qinfo, const struct reply_info* tgt_rep,
 	const struct respip_client_info* cinfo, int must_validate,
-	struct reply_info** new_repp, struct regional* region);
+	struct reply_info** new_repp, struct regional* region,
+	struct auth_zones* az);
 
 /**
  * See if any IP-based action should apply to any IP address of AAAA/A answer
@@ -148,6 +174,7 @@
  * @param alias_rrset: must not be NULL.
  * @param search_only: if true, only check if an action would apply.  actionp
  *   will be set (or intact) accordingly but the modified reply won't be built.
+ * @param az: auth zones containing RPZ information.
  * @param region: allocator to build *new_repp.
  * @return 1 on success, 0 on error.
  */
@@ -156,7 +183,7 @@
 	const struct reply_info *rep, struct reply_info** new_repp,
 	struct respip_action_info* actinfo,
 	struct ub_packed_rrset_key** alias_rrset,
-	int search_only, struct regional* region);
+	int search_only, struct regional* region, struct auth_zones* az);
 
 /**
  * Get the response-ip function block.
@@ -213,7 +240,7 @@
 /**
  * print log information for a query subject to an inform or inform-deny
  * response-ip action.
- * @param respip_addr: response-ip information that causes the action
+ * @param respip_actinfo: response-ip information that causes the action
  * @param qname: query name in the context, will be ignored if local_alias is
  *   non-NULL.
  * @param qtype: query type, in host byte order.
@@ -223,8 +250,48 @@
  *  query name.
  * @param repinfo: reply info containing the client's source address and port.
  */
-void respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
-	uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
-	struct comm_reply* repinfo);
+void respip_inform_print(struct respip_action_info* respip_actinfo,
+	uint8_t* qname, uint16_t qtype, uint16_t qclass,
+	struct local_rrset* local_alias, struct comm_reply* repinfo);
 
+/**
+ * Find resp_addr in tree, create and add to tree if it does not exist.
+ * @param set: struct containing the tree and region to alloc new node on.
+ * 	should hold write lock.
+ * @param addr: address to look up.
+ * @param addrlen: length of addr.
+ * @param net: netblock to lookup.
+ * @param create: create node if it does not exist when 1.
+ * @param ipstr: human redable ip string, for logging.
+ * @return newly created of found node, not holding lock.
+ */
+struct resp_addr*
+respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
+		socklen_t addrlen, int net, int create, const char* ipstr);
+
+/**
+ * Add RR to resp_addr's RRset. Create RRset if not existing.
+ * @param region: region to alloc RR(set).
+ * @param raddr: resp_addr containing RRset. Must hold write lock.
+ * @param rrtype: RR type.
+ * @param rrclass: RR class.
+ * @param ttl: TTL.
+ * @param rdata: RDATA.
+ * @param rdata_len: length of rdata.
+ * @param rrstr: RR as string, for logging
+ * @param netblockstr: netblock as string, for logging
+ * @return 0 on error
+ */
+int
+respip_enter_rr(struct regional* region, struct resp_addr* raddr,
+	uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
+	size_t rdata_len, const char* rrstr, const char* netblockstr);
+
+/**
+ * Delete resp_addr node from tree.
+ * @param set: struct containing tree. Must hold write lock.
+ * @param node: node to delete. Not locked.
+ */
+void
+respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
 #endif	/* RESPIP_RESPIP_H */
--- contrib/unbound/services/authzone.c.orig
+++ contrib/unbound/services/authzone.c
@@ -88,6 +88,9 @@
 #define AUTH_HTTPS_PORT 443
 /* max depth for nested $INCLUDEs */
 #define MAX_INCLUDE_DEPTH 10
+/** number of timeouts before we fallback from IXFR to AXFR,
+ * because some versions of servers (eg. dnsmasq) drop IXFR packets. */
+#define NUM_TIMEOUTS_FALLBACK_IXFR 3
 
 /** pick up nextprobe task to start waiting to perform transfer actions */
 static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
@@ -296,6 +299,8 @@
 	lock_protect(&az->lock, &az->ztree, sizeof(az->ztree));
 	lock_protect(&az->lock, &az->xtree, sizeof(az->xtree));
 	/* also lock protects the rbnode's in struct auth_zone, auth_xfer */
+	lock_rw_init(&az->rpz_lock);
+	lock_protect(&az->rpz_lock, &az->rpz_first, sizeof(az->rpz_first));
 	return az;
 }
 
@@ -378,11 +383,25 @@
 
 /** delete an auth zone structure (tree remove must be done elsewhere) */
 static void
-auth_zone_delete(struct auth_zone* z)
+auth_zone_delete(struct auth_zone* z, struct auth_zones* az)
 {
 	if(!z) return;
 	lock_rw_destroy(&z->lock);
 	traverse_postorder(&z->data, auth_data_del, NULL);
+
+	if(az && z->rpz) {
+		/* keep RPZ linked list intact */
+		lock_rw_wrlock(&az->rpz_lock);
+		if(z->rpz->prev)
+			z->rpz->prev->next = z->rpz->next;
+		else
+			az->rpz_first = z->rpz->next;
+		if(z->rpz->next)
+			z->rpz->next->prev = z->rpz->prev;
+		lock_rw_unlock(&az->rpz_lock);
+	}
+	if(z->rpz)
+		rpz_delete(z->rpz);
 	free(z->name);
 	free(z->zonefile);
 	free(z);
@@ -412,7 +431,7 @@
 	/* z lock protects all, except rbtree itself, which is az->lock */
 	if(!rbtree_insert(&az->ztree, &z->node)) {
 		lock_rw_unlock(&z->lock);
-		auth_zone_delete(z);
+		auth_zone_delete(z, NULL);
 		log_warn("duplicate auth zone");
 		return NULL;
 	}
@@ -657,23 +676,6 @@
 	}
 }
 
-/** find an rr index in the rrset.  returns true if found */
-static int
-az_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
-	size_t* index)
-{
-	size_t i;
-	for(i=0; i<d->count; i++) {
-		if(d->rr_len[i] != len)
-			continue;
-		if(memcmp(d->rr_data[i], rdata, len) == 0) {
-			*index = i;
-			return 1;
-		}
-	}
-	return 0;
-}
-
 /** find an rrsig index in the rrset.  returns true if found */
 static int
 az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
@@ -1175,6 +1177,12 @@
 		log_err("cannot add RR to domain");
 		return 0;
 	}
+	if(z->rpz) {
+		if(!(rpz_insert_rr(z->rpz, z->namelen, dname, dname_len, 
+			rr_type, rr_class, rr_ttl, rdata, rdatalen, rr,
+			rr_len)))
+			return 0;
+	}
 	return 1;
 }
 
@@ -1189,7 +1197,7 @@
 
 	/* find the plain RR of the given type */
 	if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
-		if(az_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) {
+		if(packed_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) {
 			if(rrset->data->count == 1 &&
 				rrset->data->rrsig_count == 0) {
 				/* last RR, delete the rrset */
@@ -1290,6 +1298,10 @@
 		(void)rbtree_delete(&z->data, node);
 		auth_data_delete(node);
 	}
+	if(z->rpz) {
+		rpz_remove_rr(z->rpz, z->namelen, dname, dname_len, rr_type,
+			rr_class, rdata, rdatalen);
+	}
 	return 1;
 }
 
@@ -1450,11 +1462,13 @@
  *	The lineno is set at 1 and then increased by the function.
  * @param fname: file name.
  * @param depth: recursion depth for includes
+ * @param cfg: config for chroot.
  * returns false on failure, has printed an error message
  */
 static int
 az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
-	struct sldns_file_parse_state* state, char* fname, int depth)
+	struct sldns_file_parse_state* state, char* fname, int depth,
+	struct config_file* cfg)
 {
 	size_t rr_len, dname_len;
 	int status;
@@ -1480,6 +1494,11 @@
 				/* skip spaces */
 				while(*incfile == ' ' || *incfile == '\t')
 					incfile++;
+				/* adjust for chroot on include file */
+				if(cfg->chrootdir && cfg->chrootdir[0] &&
+					strncmp(incfile, cfg->chrootdir,
+						strlen(cfg->chrootdir)) == 0)
+					incfile += strlen(cfg->chrootdir);
 				incfile = strdup(incfile);
 				if(!incfile) {
 					log_err("malloc failure");
@@ -1490,7 +1509,7 @@
 				inc = fopen(incfile, "r");
 				if(!inc) {
 					log_err("%s:%d cannot open include "
-						"file %s: %s", z->zonefile,
+						"file %s: %s", fname,
 						lineno_orig, incfile,
 						strerror(errno));
 					free(incfile);
@@ -1498,7 +1517,7 @@
 				}
 				/* recurse read that file now */
 				if(!az_parse_file(z, inc, rr, rrbuflen,
-					state, incfile, depth+1)) {
+					state, incfile, depth+1, cfg)) {
 					log_err("%s:%d cannot parse include "
 						"file %s", fname,
 						lineno_orig, incfile);
@@ -1538,30 +1557,36 @@
 }
 
 int
-auth_zone_read_zonefile(struct auth_zone* z)
+auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
 {
 	uint8_t rr[LDNS_RR_BUF_SIZE];
 	struct sldns_file_parse_state state;
+	char* zfilename;
 	FILE* in;
 	if(!z || !z->zonefile || z->zonefile[0]==0)
 		return 1; /* no file, or "", nothing to read */
+	
+	zfilename = z->zonefile;
+	if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(zfilename,
+		cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
+		zfilename += strlen(cfg->chrootdir);
 	if(verbosity >= VERB_ALGO) {
 		char nm[255+1];
 		dname_str(z->name, nm);
-		verbose(VERB_ALGO, "read zonefile %s for %s", z->zonefile, nm);
+		verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm);
 	}
-	in = fopen(z->zonefile, "r");
+	in = fopen(zfilename, "r");
 	if(!in) {
 		char* n = sldns_wire2str_dname(z->name, z->namelen);
 		if(z->zone_is_slave && errno == ENOENT) {
 			/* we fetch the zone contents later, no file yet */
 			verbose(VERB_ALGO, "no zonefile %s for %s",
-				z->zonefile, n?n:"error");
+				zfilename, n?n:"error");
 			free(n);
 			return 1;
 		}
 		log_err("cannot open zonefile %s for %s: %s",
-			z->zonefile, n?n:"error", strerror(errno));
+			zfilename, n?n:"error", strerror(errno));
 		free(n);
 		return 0;
 	}
@@ -1569,6 +1594,9 @@
 	/* clear the data tree */
 	traverse_postorder(&z->data, auth_data_del, NULL);
 	rbtree_init(&z->data, &auth_data_cmp);
+	/* clear the RPZ policies */
+	if(z->rpz)
+		rpz_clear(z->rpz);
 
 	memset(&state, 0, sizeof(state));
 	/* default TTL to 3600 */
@@ -1579,15 +1607,18 @@
 		state.origin_len = z->namelen;
 	}
 	/* parse the (toplevel) file */
-	if(!az_parse_file(z, in, rr, sizeof(rr), &state, z->zonefile, 0)) {
+	if(!az_parse_file(z, in, rr, sizeof(rr), &state, zfilename, 0, cfg)) {
 		char* n = sldns_wire2str_dname(z->name, z->namelen);
 		log_err("error parsing zonefile %s for %s",
-			z->zonefile, n?n:"error");
+			zfilename, n?n:"error");
 		free(n);
 		fclose(in);
 		return 0;
 	}
 	fclose(in);
+
+	if(z->rpz)
+		rpz_finish_config(z->rpz);
 	return 1;
 }
 
@@ -1620,7 +1651,7 @@
 	if(i >= data->count) tp = LDNS_RR_TYPE_RRSIG;
 	dat = nm;
 	datlen = nmlen;
-	w += sldns_wire2str_dname_scan(&dat, &datlen, &s, &slen, NULL, 0);
+	w += sldns_wire2str_dname_scan(&dat, &datlen, &s, &slen, NULL, 0, NULL);
 	w += sldns_str_print(&s, &slen, "\t");
 	w += sldns_str_print(&s, &slen, "%lu\t", (unsigned long)data->rr_ttl[i]);
 	w += sldns_wire2str_class_print(&s, &slen, cl);
@@ -1629,7 +1660,7 @@
 	w += sldns_str_print(&s, &slen, "\t");
 	datlen = data->rr_len[i]-2;
 	dat = data->rr_data[i]+2;
-	w += sldns_wire2str_rdata_scan(&dat, &datlen, &s, &slen, tp, NULL, 0);
+	w += sldns_wire2str_rdata_scan(&dat, &datlen, &s, &slen, tp, NULL, 0, NULL);
 
 	if(tp == LDNS_RR_TYPE_DNSKEY) {
 		w += sldns_str_print(&s, &slen, " ;{id = %u}",
@@ -1638,8 +1669,8 @@
 	}
 	w += sldns_str_print(&s, &slen, "\n");
 
-	if(w > (int)buflen) {
-		log_nametypeclass(0, "RR too long to print", nm, tp, cl);
+	if(w >= (int)buflen) {
+		log_nametypeclass(NO_VERBOSE, "RR too long to print", nm, tp, cl);
 		return 0;
 	}
 	return 1;
@@ -1710,13 +1741,13 @@
 
 /** read all auth zones from file (if they have) */
 static int
-auth_zones_read_zones(struct auth_zones* az)
+auth_zones_read_zones(struct auth_zones* az, struct config_file* cfg)
 {
 	struct auth_zone* z;
 	lock_rw_wrlock(&az->lock);
 	RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
 		lock_rw_wrlock(&z->lock);
-		if(!auth_zone_read_zonefile(z)) {
+		if(!auth_zone_read_zonefile(z, cfg)) {
 			lock_rw_unlock(&z->lock);
 			lock_rw_unlock(&az->lock);
 			return 0;
@@ -1861,6 +1892,18 @@
 	z->for_downstream = c->for_downstream;
 	z->for_upstream = c->for_upstream;
 	z->fallback_enabled = c->fallback_enabled;
+	if(c->isrpz && !z->rpz){
+		if(!(z->rpz = rpz_create(c))){
+			fatal_exit("Could not setup RPZ zones");
+			return 0;
+		}
+		lock_rw_wrlock(&az->rpz_lock);
+		z->rpz->next = az->rpz_first;
+		if(az->rpz_first)
+			az->rpz_first->prev = z->rpz;
+		az->rpz_first = z->rpz;
+		lock_rw_unlock(&az->rpz_lock);
+	}
 
 	/* xfer zone */
 	if(x) {
@@ -1931,7 +1974,7 @@
 			auth_xfer_delete(xfr);
 		}
 		(void)rbtree_delete(&az->ztree, &z->node);
-		auth_zone_delete(z);
+		auth_zone_delete(z, az);
 		z = next;
 	}
 	lock_rw_unlock(&az->lock);
@@ -1938,7 +1981,7 @@
 }
 
 int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
-	int setup)
+	int setup, int* is_rpz)
 {
 	struct config_auth* p;
 	az_setall_deleted(az);
@@ -1947,6 +1990,7 @@
 			log_warn("auth-zone without a name, skipped");
 			continue;
 		}
+		*is_rpz = (*is_rpz || p->isrpz);
 		if(!auth_zones_cfg(az, p)) {
 			log_err("cannot config auth zone %s", p->name);
 			return 0;
@@ -1953,7 +1997,7 @@
 		}
 	}
 	az_delete_deleted_zones(az);
-	if(!auth_zones_read_zones(az))
+	if(!auth_zones_read_zones(az, cfg))
 		return 0;
 	if(setup) {
 		if(!auth_zones_setup_zones(az))
@@ -2026,11 +2070,13 @@
 	if(xfr->task_probe) {
 		auth_free_masters(xfr->task_probe->masters);
 		comm_point_delete(xfr->task_probe->cp);
+		comm_timer_delete(xfr->task_probe->timer);
 		free(xfr->task_probe);
 	}
 	if(xfr->task_transfer) {
 		auth_free_masters(xfr->task_transfer->masters);
 		comm_point_delete(xfr->task_transfer->cp);
+		comm_timer_delete(xfr->task_transfer->timer);
 		if(xfr->task_transfer->chunks_first) {
 			auth_chunks_delete(xfr->task_transfer);
 		}
@@ -2045,7 +2091,7 @@
 auth_zone_del(rbnode_type* n, void* ATTR_UNUSED(arg))
 {
 	struct auth_zone* z = (struct auth_zone*)n->key;
-	auth_zone_delete(z);
+	auth_zone_delete(z, NULL);
 }
 
 /** helper traverse to delete xfer zones */
@@ -2060,6 +2106,7 @@
 {
 	if(!az) return;
 	lock_rw_destroy(&az->lock);
+	lock_rw_destroy(&az->rpz_lock);
 	traverse_postorder(&az->ztree, auth_zone_del, NULL);
 	traverse_postorder(&az->xtree, auth_xfer_del, NULL);
 	free(az);
@@ -2362,6 +2409,10 @@
 		return 0; /* rdatalen in DNAME rdata is malformed */
 	if(dname_valid(dtarg, dtarglen) != dtarglen)
 		return 0; /* DNAME RR has malformed rdata */
+	if(qname_len == 0)
+		return 0; /* too short */
+	if(qname_len <= node->namelen)
+		return 0; /* qname too short for dname removal */
 
 	/* synthesize a CNAME */
 	newlen = synth_cname_buf(qname, qname_len, node->namelen,
@@ -2564,12 +2615,14 @@
 	/* hashfunc(name, salt) */
 	memmove(p, nm, nmlen);
 	query_dname_tolower(p);
-	memmove(p+nmlen, salt, saltlen);
+	if(salt && saltlen > 0)
+		memmove(p+nmlen, salt, saltlen);
 	(void)secalgo_nsec3_hash(algo, p, nmlen+saltlen, (unsigned char*)buf);
 	for(i=0; i<iter; i++) {
 		/* hashfunc(hash, salt) */
 		memmove(p, buf, hlen);
-		memmove(p+hlen, salt, saltlen);
+		if(salt && saltlen > 0)
+			memmove(p+hlen, salt, saltlen);
 		(void)secalgo_nsec3_hash(algo, p, hlen+saltlen,
 			(unsigned char*)buf);
 	}
@@ -2730,6 +2783,8 @@
  * 	that is an exact match that should exist for it.
  * 	If that does not exist, a higher exact match + nxproof is enabled
  * 	(for some sort of opt-out empty nonterminal cases).
+ * nodataproof: search for exact match and include that instead.
+ * ceproof: include ce proof NSEC3 (omitted for wildcard replies).
  * nxproof: include denial of the qname.
  * wcproof: include denial of wildcard (wildcard.ce).
  */
@@ -2736,7 +2791,8 @@
 static int
 az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
 	struct dns_msg* msg, uint8_t* cenm, size_t cenmlen, uint8_t* qname,
-	size_t qname_len, int nxproof, int wcproof)
+	size_t qname_len, int nodataproof, int ceproof, int nxproof,
+	int wcproof)
 {
 	int algo;
 	size_t iter, saltlen;
@@ -2747,12 +2803,27 @@
 	/* find parameters of nsec3 proof */
 	if(!az_nsec3_param(z, &algo, &iter, &salt, &saltlen))
 		return 1; /* no nsec3 */
+	if(nodataproof) {
+		/* see if the node has a hash of itself for the nodata
+		 * proof nsec3, this has to be an exact match nsec3. */
+		struct auth_data* match;
+		match = az_nsec3_find_exact(z, qname, qname_len, algo,
+			iter, salt, saltlen);
+		if(match) {
+			if(!az_nsec3_insert(z, region, msg, match))
+				return 0;
+			/* only nodata NSEC3 needed, no CE or others. */
+			return 1;
+		}
+	}
 	/* find ce that has an NSEC3 */
-	node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce,
-		algo, iter, salt, saltlen);
-	if(no_exact_ce) nxproof = 1;
-	if(!az_nsec3_insert(z, region, msg, node))
-		return 0;
+	if(ceproof) {
+		node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce,
+			algo, iter, salt, saltlen);
+		if(no_exact_ce) nxproof = 1;
+		if(!az_nsec3_insert(z, region, msg, node))
+			return 0;
+	}
 
 	if(nxproof) {
 		uint8_t* nx;
@@ -2828,7 +2899,7 @@
 		if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
 		added++;
 	}
-	if(added == 0 && node->rrsets) {
+	if(added == 0 && node && node->rrsets) {
 		if(!msg_add_rrset_an(z, region, msg, node,
 			node->rrsets)) return 0;
 	}
@@ -2897,7 +2968,7 @@
 		/* DNSSEC denial NSEC3 */
 		if(!az_add_nsec3_proof(z, region, msg, node->name,
 			node->namelen, msg->qinfo.qname,
-			msg->qinfo.qname_len, 0, 0))
+			msg->qinfo.qname_len, 1, 1, 0, 0))
 			return 0;
 	}
 	return 1;
@@ -2924,7 +2995,7 @@
 		} else {
 			if(!az_add_nsec3_proof(z, region, msg, ce->name,
 				ce->namelen, msg->qinfo.qname,
-				msg->qinfo.qname_len, 0, 0))
+				msg->qinfo.qname_len, 1, 1, 0, 0))
 				return 0;
 		}
 	}
@@ -2963,6 +3034,7 @@
 	struct auth_data* wildcard, struct auth_data* node)
 {
 	struct auth_rrset* rrset, *nsec;
+	int insert_ce = 0;
 	if((rrset=az_domain_rrset(wildcard, qinfo->qtype)) != NULL) {
 		/* wildcard has type, add it */
 		if(!msg_add_rrset_an(z, region, msg, wildcard, rrset))
@@ -2989,6 +3061,10 @@
 		/* call other notype routine for dnssec notype denials */
 		if(!az_generate_notype_answer(z, region, msg, wildcard))
 			return 0;
+		/* because the notype, there is no positive data with an
+		 * RRSIG that indicates the wildcard position.  Thus the
+		 * wildcard qname denial needs to have a CE nsec3. */
+		insert_ce = 1;
 	}
 
 	/* ce and node for dnssec denial of wildcard original name */
@@ -2995,9 +3071,12 @@
 	if((nsec=az_find_nsec_cover(z, &node)) != NULL) {
 		if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0;
 	} else if(ce) {
-		if(!az_add_nsec3_proof(z, region, msg, ce->name,
-			ce->namelen, msg->qinfo.qname,
-			msg->qinfo.qname_len, 1, 0))
+		uint8_t* wildup = wildcard->name;
+		size_t wilduplen= wildcard->namelen;
+		dname_remove_label(&wildup, &wilduplen);
+		if(!az_add_nsec3_proof(z, region, msg, wildup,
+			wilduplen, msg->qinfo.qname,
+			msg->qinfo.qname_len, 0, insert_ce, 1, 0))
 			return 0;
 	}
 
@@ -3023,7 +3102,7 @@
 	} else if(ce) {
 		if(!az_add_nsec3_proof(z, region, msg, ce->name,
 			ce->namelen, msg->qinfo.qname,
-			msg->qinfo.qname_len, 1, 1))
+			msg->qinfo.qname_len, 0, 1, 1, 1))
 			return 0;
 	}
 	return 1;
@@ -3163,6 +3242,11 @@
 		*fallback = 1;
 		return 0;
 	}
+	if(z->zone_expired) {
+		*fallback = z->fallback_enabled;
+		lock_rw_unlock(&z->lock);
+		return 0;
+	}
 	/* see what answer that zone would generate */
 	r = auth_zone_generate_answer(z, qinfo, region, msg, fallback);
 	lock_rw_unlock(&z->lock);
@@ -3250,6 +3334,19 @@
 		lock_rw_unlock(&z->lock);
 		return 0;
 	}
+	if(z->zone_expired) {
+		if(z->fallback_enabled) {
+			lock_rw_unlock(&z->lock);
+			return 0;
+		}
+		lock_rw_unlock(&z->lock);
+		lock_rw_wrlock(&az->lock);
+		az->num_query_down++;
+		lock_rw_unlock(&az->lock);
+		auth_error_encode(qinfo, env, edns, repinfo, buf, temp,
+			LDNS_RCODE_SERVFAIL);
+		return 1;
+	}
 
 	/* answer it from zone z */
 	r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
@@ -3636,6 +3733,7 @@
 xfr_transfer_start_lookups(struct auth_xfer* xfr)
 {
 	/* delete all the looked up addresses in the list */
+	xfr->task_transfer->scan_addr = NULL;
 	xfr_masterlist_free_addrs(xfr->task_transfer->masters);
 
 	/* start lookup at the first master */
@@ -3666,6 +3764,7 @@
 xfr_probe_start_lookups(struct auth_xfer* xfr)
 {
 	/* delete all the looked up addresses in the list */
+	xfr->task_probe->scan_addr = NULL;
 	xfr_masterlist_free_addrs(xfr->task_probe->masters);
 
 	/* start lookup at the first master */
@@ -4620,6 +4719,10 @@
 	/* clear the data tree */
 	traverse_postorder(&z->data, auth_data_del, NULL);
 	rbtree_init(&z->data, &auth_data_cmp);
+	/* clear the RPZ policies */
+	if(z->rpz)
+		rpz_clear(z->rpz);
+
 	xfr->have_zone = 0;
 	xfr->serial = 0;
 
@@ -4716,6 +4819,10 @@
 	/* clear the data tree */
 	traverse_postorder(&z->data, auth_data_del, NULL);
 	rbtree_init(&z->data, &auth_data_cmp);
+	/* clear the RPZ policies */
+	if(z->rpz)
+		rpz_clear(z->rpz);
+
 	xfr->have_zone = 0;
 	xfr->serial = 0;
 
@@ -4773,8 +4880,10 @@
 static void
 xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
 {
+	struct config_file* cfg = env->cfg;
 	struct auth_zone* z;
 	char tmpfile[1024];
+	char* zfilename;
 	lock_basic_unlock(&xfr->lock);
 
 	/* get lock again, so it is a readlock and concurrently queries
@@ -4792,20 +4901,29 @@
 	lock_basic_lock(&xfr->lock);
 	lock_rw_unlock(&env->auth_zones->lock);
 
-	if(z->zonefile == NULL) {
+	if(z->zonefile == NULL || z->zonefile[0] == 0) {
 		lock_rw_unlock(&z->lock);
 		/* no write needed, no zonefile set */
 		return;
 	}
+	zfilename = z->zonefile;
+	if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(zfilename,
+		cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
+		zfilename += strlen(cfg->chrootdir);
+	if(verbosity >= VERB_ALGO) {
+		char nm[255+1];
+		dname_str(z->name, nm);
+		verbose(VERB_ALGO, "write zonefile %s for %s", zfilename, nm);
+	}
 
 	/* write to tempfile first */
-	if((size_t)strlen(z->zonefile) + 16 > sizeof(tmpfile)) {
+	if((size_t)strlen(zfilename) + 16 > sizeof(tmpfile)) {
 		verbose(VERB_ALGO, "tmpfilename too long, cannot update "
-			" zonefile %s", z->zonefile);
+			" zonefile %s", zfilename);
 		lock_rw_unlock(&z->lock);
 		return;
 	}
-	snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", z->zonefile,
+	snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", zfilename,
 		(unsigned)getpid());
 	if(xfr->task_transfer->master->http) {
 		/* use the stored chunk list to write them */
@@ -4812,6 +4930,7 @@
 		if(!auth_zone_write_chunks(xfr, tmpfile)) {
 			unlink(tmpfile);
 			lock_rw_unlock(&z->lock);
+			return;
 		}
 	} else if(!auth_zone_write_file(z, tmpfile)) {
 		unlink(tmpfile);
@@ -4818,8 +4937,8 @@
 		lock_rw_unlock(&z->lock);
 		return;
 	}
-	if(rename(tmpfile, z->zonefile) < 0) {
-		log_err("could not rename(%s, %s): %s", tmpfile, z->zonefile,
+	if(rename(tmpfile, zfilename) < 0) {
+		log_err("could not rename(%s, %s): %s", tmpfile, zfilename,
 			strerror(errno));
 		unlink(tmpfile);
 		lock_rw_unlock(&z->lock);
@@ -4889,6 +5008,9 @@
 	if(xfr->have_zone)
 		xfr->lease_time = *env->now;
 
+	if(z->rpz)
+		rpz_finish_config(z->rpz);
+
 	/* unlock */
 	lock_rw_unlock(&z->lock);
 
@@ -4907,6 +5029,9 @@
 static void
 xfr_transfer_disown(struct auth_xfer* xfr)
 {
+	/* remove timer (from this worker's event base) */
+	comm_timer_delete(xfr->task_transfer->timer);
+	xfr->task_transfer->timer = NULL;
 	/* remove the commpoint */
 	comm_point_delete(xfr->task_transfer->cp);
 	xfr->task_transfer->cp = NULL;
@@ -4951,12 +5076,12 @@
 		qinfo.qtype = LDNS_RR_TYPE_AAAA;
 	qinfo.local_alias = NULL;
 	if(verbosity >= VERB_ALGO) {
-		char buf[512];
+		char buf1[512];
 		char buf2[LDNS_MAX_DOMAINLEN+1];
 		dname_str(xfr->name, buf2);
-		snprintf(buf, sizeof(buf), "auth zone %s: master lookup"
+		snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
 			" for task_transfer", buf2);
-		log_query_info(VERB_ALGO, buf, &qinfo);
+		log_query_info(VERB_ALGO, buf1, &qinfo);
 	}
 	edns.edns_present = 1;
 	edns.ext_rcode = 0;
@@ -4988,6 +5113,9 @@
 	struct sockaddr_storage addr;
 	socklen_t addrlen = 0;
 	struct auth_master* master = xfr->task_transfer->master;
+	char *auth_name = NULL;
+	struct timeval t;
+	int timeout;
 	if(!master) return 0;
 	if(master->allow_notify) return 0; /* only for notify */
 
@@ -4996,7 +5124,7 @@
 		addrlen = xfr->task_transfer->scan_addr->addrlen;
 		memmove(&addr, &xfr->task_transfer->scan_addr->addr, addrlen);
 	} else {
-		if(!extstrtoaddr(master->host, &addr, &addrlen)) {
+		if(!authextstrtoaddr(master->host, &addr, &addrlen, &auth_name)) {
 			/* the ones that are not in addr format are supposed
 			 * to be looked up.  The lookup has failed however,
 			 * so skip them */
@@ -5013,25 +5141,46 @@
 		comm_point_delete(xfr->task_transfer->cp);
 		xfr->task_transfer->cp = NULL;
 	}
+	if(!xfr->task_transfer->timer) {
+		xfr->task_transfer->timer = comm_timer_create(env->worker_base,
+			auth_xfer_transfer_timer_callback, xfr);
+		if(!xfr->task_transfer->timer) {
+			log_err("malloc failure");
+			return 0;
+		}
+	}
+	timeout = AUTH_TRANSFER_TIMEOUT;
+#ifndef S_SPLINT_S
+        t.tv_sec = timeout/1000;
+        t.tv_usec = (timeout%1000)*1000;
+#endif
 
 	if(master->http) {
 		/* perform http fetch */
 		/* store http port number into sockaddr,
 		 * unless someone used unbound's host@port notation */
+		xfr->task_transfer->on_ixfr = 0;
 		if(strchr(master->host, '@') == NULL)
 			sockaddr_store_port(&addr, addrlen, master->port);
 		xfr->task_transfer->cp = outnet_comm_point_for_http(
 			env->outnet, auth_xfer_transfer_http_callback, xfr,
-			&addr, addrlen, AUTH_TRANSFER_TIMEOUT, master->ssl,
-			master->host, master->file);
+			&addr, addrlen, -1, master->ssl, master->host,
+			master->file);
 		if(!xfr->task_transfer->cp) {
-			char zname[255+1];
+			char zname[255+1], as[256];
 			dname_str(xfr->name, zname);
+			addr_to_str(&addr, addrlen, as, sizeof(as));
 			verbose(VERB_ALGO, "cannot create http cp "
-				"connection for %s to %s", zname,
-				master->host);
+				"connection for %s to %s", zname, as);
 			return 0;
 		}
+		comm_timer_set(xfr->task_transfer->timer, &t);
+		if(verbosity >= VERB_ALGO) {
+			char zname[255+1], as[256];
+			dname_str(xfr->name, zname);
+			addr_to_str(&addr, addrlen, as, sizeof(as));
+			verbose(VERB_ALGO, "auth zone %s transfer next HTTP fetch from %s started", zname, as);
+		}
 		return 1;
 	}
 
@@ -5045,14 +5194,24 @@
 	/* connect on fd */
 	xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
 		auth_xfer_transfer_tcp_callback, xfr, &addr, addrlen,
-		env->scratch_buffer, AUTH_TRANSFER_TIMEOUT);
+		env->scratch_buffer, -1,
+		auth_name != NULL, auth_name);
 	if(!xfr->task_transfer->cp) {
-		char zname[255+1];
-		dname_str(xfr->name, zname);
+		char zname[255+1], as[256];
+ 		dname_str(xfr->name, zname);
+		addr_to_str(&addr, addrlen, as, sizeof(as));
 		verbose(VERB_ALGO, "cannot create tcp cp connection for "
-			"xfr %s to %s", zname, master->host);
+			"xfr %s to %s", zname, as);
 		return 0;
 	}
+	comm_timer_set(xfr->task_transfer->timer, &t);
+	if(verbosity >= VERB_ALGO) {
+		char zname[255+1], as[256];
+ 		dname_str(xfr->name, zname);
+		addr_to_str(&addr, addrlen, as, sizeof(as));
+		verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname, 
+			(xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as);
+	}
 	return 1;
 }
 
@@ -5070,6 +5229,11 @@
 			 * and we may then get an instant cache response,
 			 * and that calls the callback just like a full
 			 * lookup and lookup failures also call callback */
+			if(verbosity >= VERB_ALGO) {
+				char zname[255+1];
+				dname_str(xfr->name, zname);
+				verbose(VERB_ALGO, "auth zone %s transfer next target lookup", zname);
+			}
 			lock_basic_unlock(&xfr->lock);
 			return;
 		}
@@ -5088,6 +5252,11 @@
 		/* failed to fetch, next master */
 		xfr_transfer_nextmaster(xfr);
 	}
+	if(verbosity >= VERB_ALGO) {
+		char zname[255+1];
+		dname_str(xfr->name, zname);
+		verbose(VERB_ALGO, "auth zone %s transfer failed, wait", zname);
+	}
 
 	/* we failed to fetch the zone, move to wait task
 	 * use the shorter retry timeout */
@@ -5185,8 +5354,26 @@
 			if(answer) {
 				xfr_master_add_addrs(xfr->task_transfer->
 					lookup_target, answer, wanted_qtype);
+			} else {
+				if(verbosity >= VERB_ALGO) {
+					char zname[255+1];
+					dname_str(xfr->name, zname);
+					verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has nodata", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
+				}
 			}
+		} else {
+			if(verbosity >= VERB_ALGO) {
+				char zname[255+1];
+				dname_str(xfr->name, zname);
+				verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
+			}
 		}
+	} else {
+		if(verbosity >= VERB_ALGO) {
+			char zname[255+1];
+			dname_str(xfr->name, zname);
+			verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup failed", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
+		}
 	}
 	if(xfr->task_transfer->lookup_target->list &&
 		xfr->task_transfer->lookup_target == xfr_transfer_current_master(xfr))
@@ -5385,9 +5572,12 @@
 				xfr->task_transfer->rr_scan_num == 0 &&
 				LDNS_ANCOUNT(wire)==1) {
 				verbose(VERB_ALGO, "xfr to %s ended, "
-					"IXFR reply that zone has serial %u",
+					"IXFR reply that zone has serial %u,"
+					" fallback from IXFR to AXFR",
 					xfr->task_transfer->master->host,
 					(unsigned)serial);
+				xfr->task_transfer->ixfr_fail = 1;
+				*gonextonfail = 0;
 				return 0;
 			}
 
@@ -5570,6 +5760,46 @@
 	xfr_transfer_nexttarget_or_end(xfr, env);
 }
 
+/** callback for the task_transfer timer */
+void
+auth_xfer_transfer_timer_callback(void* arg)
+{
+	struct auth_xfer* xfr = (struct auth_xfer*)arg;
+	struct module_env* env;
+	int gonextonfail = 1;
+	log_assert(xfr->task_transfer);
+	lock_basic_lock(&xfr->lock);
+	env = xfr->task_transfer->env;
+	if(env->outnet->want_to_quit) {
+		lock_basic_unlock(&xfr->lock);
+		return; /* stop on quit */
+	}
+
+	verbose(VERB_ALGO, "xfr stopped, connection timeout to %s",
+		xfr->task_transfer->master->host);
+
+	/* see if IXFR caused the failure, if so, try AXFR */
+	if(xfr->task_transfer->on_ixfr) {
+		xfr->task_transfer->ixfr_possible_timeout_count++;
+		if(xfr->task_transfer->ixfr_possible_timeout_count >=
+			NUM_TIMEOUTS_FALLBACK_IXFR) {
+			verbose(VERB_ALGO, "xfr to %s, fallback "
+				"from IXFR to AXFR (because of timeouts)",
+				xfr->task_transfer->master->host);
+			xfr->task_transfer->ixfr_fail = 1;
+			gonextonfail = 0;
+		}
+	}
+
+	/* delete transferred data from list */
+	auth_chunks_delete(xfr->task_transfer);
+	comm_point_delete(xfr->task_transfer->cp);
+	xfr->task_transfer->cp = NULL;
+	if(gonextonfail)
+		xfr_transfer_nextmaster(xfr);
+	xfr_transfer_nexttarget_or_end(xfr, env);
+}
+
 /** callback for task_transfer tcp connections */
 int
 auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
@@ -5586,6 +5816,8 @@
 		lock_basic_unlock(&xfr->lock);
 		return 0; /* stop on quit */
 	}
+	/* stop the timer */
+	comm_timer_disable(xfr->task_transfer->timer);
 
 	if(err != NETEVENT_NOERROR) {
 		/* connection failed, closed, or timeout */
@@ -5593,15 +5825,33 @@
 		 * and continue task_transfer*/
 		verbose(VERB_ALGO, "xfr stopped, connection lost to %s",
 			xfr->task_transfer->master->host);
+
+		/* see if IXFR caused the failure, if so, try AXFR */
+		if(xfr->task_transfer->on_ixfr) {
+			xfr->task_transfer->ixfr_possible_timeout_count++;
+			if(xfr->task_transfer->ixfr_possible_timeout_count >=
+				NUM_TIMEOUTS_FALLBACK_IXFR) {
+				verbose(VERB_ALGO, "xfr to %s, fallback "
+					"from IXFR to AXFR (because of timeouts)",
+					xfr->task_transfer->master->host);
+				xfr->task_transfer->ixfr_fail = 1;
+				gonextonfail = 0;
+			}
+		}
+
 	failed:
 		/* delete transferred data from list */
 		auth_chunks_delete(xfr->task_transfer);
 		comm_point_delete(xfr->task_transfer->cp);
 		xfr->task_transfer->cp = NULL;
-		xfr_transfer_nextmaster(xfr);
+		if(gonextonfail)
+			xfr_transfer_nextmaster(xfr);
 		xfr_transfer_nexttarget_or_end(xfr, env);
 		return 0;
 	}
+	/* note that IXFR worked without timeout */
+	if(xfr->task_transfer->on_ixfr)
+		xfr->task_transfer->ixfr_possible_timeout_count = 0;
 
 	/* handle returned packet */
 	/* if it fails, cleanup and end this transfer */
@@ -5648,6 +5898,8 @@
 		return 0; /* stop on quit */
 	}
 	verbose(VERB_ALGO, "auth zone transfer http callback");
+	/* stop the timer */
+	comm_timer_disable(xfr->task_transfer->timer);
 
 	if(err != NETEVENT_NOERROR && err != NETEVENT_DONE) {
 		/* connection failed, closed, or timeout */
@@ -5745,6 +5997,7 @@
 	struct timeval t;
 	/* pick master */
 	struct auth_master* master = xfr_probe_current_master(xfr);
+	char *auth_name = NULL;
 	if(!master) return 0;
 	if(master->allow_notify) return 0; /* only for notify */
 	if(master->http) return 0; /* only masters get SOA UDP probe,
@@ -5755,7 +6008,7 @@
 		addrlen = xfr->task_probe->scan_addr->addrlen;
 		memmove(&addr, &xfr->task_probe->scan_addr->addr, addrlen);
 	} else {
-		if(!extstrtoaddr(master->host, &addr, &addrlen)) {
+		if(!authextstrtoaddr(master->host, &addr, &addrlen, &auth_name)) {
 			/* the ones that are not in addr format are supposed
 			 * to be looked up.  The lookup has failed however,
 			 * so skip them */
@@ -5765,6 +6018,18 @@
 				zname, master->host);
 			return 0;
 		}
+		if (auth_name != NULL) {
+			if (addr.ss_family == AF_INET
+			&&  (int)ntohs(((struct sockaddr_in *)&addr)->sin_port)
+		            == env->cfg->ssl_port)
+				((struct sockaddr_in *)&addr)->sin_port
+					= htons((uint16_t)env->cfg->port);
+			else if (addr.ss_family == AF_INET6
+			&&  (int)ntohs(((struct sockaddr_in6 *)&addr)->sin6_port)
+		            == env->cfg->ssl_port)
+                        	((struct sockaddr_in6 *)&addr)->sin6_port
+					= htons((uint16_t)env->cfg->port);
+		}
 	}
 
 	/* create packet */
@@ -5774,14 +6039,26 @@
 		xfr->task_probe->id = (uint16_t)(ub_random(env->rnd)&0xffff);
 	xfr_create_soa_probe_packet(xfr, env->scratch_buffer, 
 		xfr->task_probe->id);
+	/* we need to remove the cp if we have a different ip4/ip6 type now */
+	if(xfr->task_probe->cp &&
+		((xfr->task_probe->cp_is_ip6 && !addr_is_ip6(&addr, addrlen)) ||
+		(!xfr->task_probe->cp_is_ip6 && addr_is_ip6(&addr, addrlen)))
+		) {
+		comm_point_delete(xfr->task_probe->cp);
+		xfr->task_probe->cp = NULL;
+	}
 	if(!xfr->task_probe->cp) {
+		if(addr_is_ip6(&addr, addrlen))
+			xfr->task_probe->cp_is_ip6 = 1;
+		else 	xfr->task_probe->cp_is_ip6 = 0;
 		xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
 			auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
 		if(!xfr->task_probe->cp) {
-			char zname[255+1];
+			char zname[255+1], as[256];
 			dname_str(xfr->name, zname);
+			addr_to_str(&addr, addrlen, as, sizeof(as));
 			verbose(VERB_ALGO, "cannot create udp cp for "
-				"probe %s to %s", zname, master->host);
+				"probe %s to %s", zname, as);
 			return 0;
 		}
 	}
@@ -5797,12 +6074,20 @@
 	/* send udp packet */
 	if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer,
 		(struct sockaddr*)&addr, addrlen)) {
-		char zname[255+1];
+		char zname[255+1], as[256];
 		dname_str(xfr->name, zname);
+		addr_to_str(&addr, addrlen, as, sizeof(as));
 		verbose(VERB_ALGO, "failed to send soa probe for %s to %s",
-			zname, master->host);
+			zname, as);
 		return 0;
 	}
+	if(verbosity >= VERB_ALGO) {
+		char zname[255+1], as[256];
+		dname_str(xfr->name, zname);
+		addr_to_str(&addr, addrlen, as, sizeof(as));
+		verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
+			as);
+	}
 	xfr->task_probe->timeout = timeout;
 #ifndef S_SPLINT_S
 	t.tv_sec = timeout/1000;
@@ -5827,6 +6112,11 @@
 		return; /* stop on quit */
 	}
 
+	if(verbosity >= VERB_ALGO) {
+		char zname[255+1];
+		dname_str(xfr->name, zname);
+		verbose(VERB_ALGO, "auth zone %s soa probe timeout", zname);
+	}
 	if(xfr->task_probe->timeout <= AUTH_PROBE_TIMEOUT_STOP) {
 		/* try again with bigger timeout */
 		if(xfr_probe_send_probe(xfr, env, xfr->task_probe->timeout*2)) {
@@ -5973,12 +6263,12 @@
 		qinfo.qtype = LDNS_RR_TYPE_AAAA;
 	qinfo.local_alias = NULL;
 	if(verbosity >= VERB_ALGO) {
-		char buf[512];
+		char buf1[512];
 		char buf2[LDNS_MAX_DOMAINLEN+1];
 		dname_str(xfr->name, buf2);
-		snprintf(buf, sizeof(buf), "auth zone %s: master lookup"
+		snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
 			" for task_probe", buf2);
-		log_query_info(VERB_ALGO, buf, &qinfo);
+		log_query_info(VERB_ALGO, buf1, &qinfo);
 	}
 	edns.edns_present = 1;
 	edns.ext_rcode = 0;
@@ -6014,6 +6304,11 @@
 			 * and we may then get an instant cache response,
 			 * and that calls the callback just like a full
 			 * lookup and lookup failures also call callback */
+			if(verbosity >= VERB_ALGO) {
+				char zname[255+1];
+				dname_str(xfr->name, zname);
+				verbose(VERB_ALGO, "auth zone %s probe next target lookup", zname);
+			}
 			lock_basic_unlock(&xfr->lock);
 			return;
 		}
@@ -6022,9 +6317,19 @@
 	/* probe of list has ended.  Create or refresh the list of of
 	 * allow_notify addrs */
 	probe_copy_masters_for_allow_notify(xfr);
+	if(verbosity >= VERB_ALGO) {
+		char zname[255+1];
+		dname_str(xfr->name, zname);
+		verbose(VERB_ALGO, "auth zone %s probe: notify addrs updated", zname);
+	}
 	if(xfr->task_probe->only_lookup) {
 		/* only wanted lookups for copy, stop probe and start wait */
 		xfr->task_probe->only_lookup = 0;
+		if(verbosity >= VERB_ALGO) {
+			char zname[255+1];
+			dname_str(xfr->name, zname);
+			verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname);
+		}
 		xfr_probe_disown(xfr);
 		if(xfr->task_nextprobe->worker == NULL)
 			xfr_set_timeout(xfr, env, 0, 0);
@@ -6046,7 +6351,11 @@
 	/* done with probe sequence, wait */
 	if(xfr->task_probe->have_new_lease) {
 		/* if zone not updated, start the wait timer again */
-		verbose(VERB_ALGO, "auth_zone unchanged, new lease, wait");
+		if(verbosity >= VERB_ALGO) {
+			char zname[255+1];
+			dname_str(xfr->name, zname);
+			verbose(VERB_ALGO, "auth_zone %s unchanged, new lease, wait", zname);
+		}
 		xfr_probe_disown(xfr);
 		if(xfr->have_zone)
 			xfr->lease_time = *env->now;
@@ -6053,6 +6362,11 @@
 		if(xfr->task_nextprobe->worker == NULL)
 			xfr_set_timeout(xfr, env, 0, 0);
 	} else {
+		if(verbosity >= VERB_ALGO) {
+			char zname[255+1];
+			dname_str(xfr->name, zname);
+			verbose(VERB_ALGO, "auth zone %s soa probe failed, wait to retry", zname);
+		}
 		/* we failed to send this as well, move to the wait task,
 		 * use the shorter retry timeout */
 		xfr_probe_disown(xfr);
@@ -6097,8 +6411,26 @@
 			if(answer) {
 				xfr_master_add_addrs(xfr->task_probe->
 					lookup_target, answer, wanted_qtype);
+			} else {
+				if(verbosity >= VERB_ALGO) {
+					char zname[255+1];
+					dname_str(xfr->name, zname);
+					verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has nodata", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
+				}
 			}
+		} else {
+			if(verbosity >= VERB_ALGO) {
+				char zname[255+1];
+				dname_str(xfr->name, zname);
+				verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
+			}
 		}
+	} else {
+		if(verbosity >= VERB_ALGO) {
+			char zname[255+1];
+			dname_str(xfr->name, zname);
+			verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup failed", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
+		}
 	}
 	if(xfr->task_probe->lookup_target->list &&
 		xfr->task_probe->lookup_target == xfr_probe_current_master(xfr))
@@ -6286,7 +6618,7 @@
 		/* don't lookup_only, if lookup timeout is 0 anyway,
 		 * or if we don't have masters to lookup */
 		tv.tv_sec = 0;
-		if(xfr->task_probe && xfr->task_probe->worker == NULL)
+		if(xfr->task_probe->worker == NULL)
 			xfr->task_probe->only_lookup = 1;
 	}
 	if(verbosity >= VERB_ALGO) {
--- contrib/unbound/services/authzone.h.orig
+++ contrib/unbound/services/authzone.h
@@ -46,6 +46,7 @@
 #include "util/rbtree.h"
 #include "util/locks.h"
 #include "services/mesh.h"
+#include "services/rpz.h"
 struct ub_packed_rrset_key;
 struct regional;
 struct config_file;
@@ -81,6 +82,11 @@
 	size_t num_query_up;
 	/** number of queries downstream */
 	size_t num_query_down;
+	/** first rpz item in linked list */
+	struct rpz* rpz_first;
+	/** rw lock for rpz linked list, needed when iterating or editing linked
+	 * list. */
+	lock_rw_type rpz_lock;
 };
 
 /**
@@ -126,6 +132,8 @@
 	/** for upstream: this zone answers queries that unbound intends to
 	 * send upstream. */
 	int for_upstream;
+	/** RPZ zones */
+	struct rpz* rpz;
 	/** zone has been deleted */
 	int zone_deleted;
 	/** deletelist pointer, unused normally except during delete */
@@ -327,6 +335,8 @@
 	/** the SOA probe udp event.
 	 * on the workers event base. */
 	struct comm_point* cp;
+	/** is the cp for ip6 or ip4 */
+	int cp_is_ip6;
 	/** timeout for packets.
 	 * on the workers event base. */
 	struct comm_timer* timer;
@@ -378,6 +388,8 @@
 	 * data or add of duplicate data).  Flag is cleared once the retry
 	 * with axfr is done. */
 	int ixfr_fail;
+	/** we saw an ixfr-indicating timeout, count of them */
+	int ixfr_possible_timeout_count;
 	/** we are doing IXFR right now */
 	int on_ixfr;
 	/** did we detect the current AXFR/IXFR serial number yet, 0 not yet,
@@ -396,6 +408,9 @@
 	/** the transfer (TCP) to the master.
 	 * on the workers event base. */
 	struct comm_point* cp;
+	/** timeout for the transfer.
+	 * on the workers event base. */
+	struct comm_timer* timer;
 };
 
 /** list of addresses */
@@ -453,10 +468,11 @@
  * @param az: auth zones structure
  * @param cfg: config to apply.
  * @param setup: if true, also sets up values in the auth zones structure
+ * @param is_rpz: set to 1 if at least one RPZ zone is configured.
  * @return false on failure.
  */
 int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
-	int setup);
+	int setup, int* is_rpz);
 
 /** initial pick up of worker timeouts, ties events to worker event loop
  * @param az: auth zones structure
@@ -599,7 +615,7 @@
 	struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t dclass);
 
 /** read auth zone from zonefile. caller must lock zone. false on failure */
-int auth_zone_read_zonefile(struct auth_zone* z);
+int auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg);
 
 /** find serial number of zone or false if none (no SOA record) */
 int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
@@ -645,6 +661,8 @@
         struct comm_reply* repinfo);
 /** xfer probe timeout callback, part of task_probe */
 void auth_xfer_probe_timer_callback(void* arg);
+/** xfer transfer timeout callback, part of task_transfer */
+void auth_xfer_transfer_timer_callback(void* arg);
 /** mesh callback for task_probe on lookup of host names */
 void auth_xfer_probe_lookup_callback(void* arg, int rcode,
 	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
--- contrib/unbound/services/cache/dns.c.orig
+++ contrib/unbound/services/cache/dns.c
@@ -40,10 +40,12 @@
  */
 #include "config.h"
 #include "iterator/iter_delegpt.h"
+#include "iterator/iter_utils.h"
 #include "validator/val_nsec.h"
 #include "validator/val_utils.h"
 #include "services/cache/dns.h"
 #include "services/cache/rrset.h"
+#include "util/data/msgparse.h"
 #include "util/data/msgreply.h"
 #include "util/data/packed_rrset.h"
 #include "util/data/dname.h"
@@ -72,15 +74,15 @@
 	time_t leeway, int pside, struct reply_info* qrep,
 	struct regional* region)
 {
-        size_t i;
-        /* see if rrset already exists in cache, if not insert it. */
-        for(i=0; i<rep->rrset_count; i++) {
-                rep->ref[i].key = rep->rrsets[i];
-                rep->ref[i].id = rep->rrsets[i]->id;
-		/* update ref if it was in the cache */ 
+	size_t i;
+	/* see if rrset already exists in cache, if not insert it. */
+	for(i=0; i<rep->rrset_count; i++) {
+		rep->ref[i].key = rep->rrsets[i];
+		rep->ref[i].id = rep->rrsets[i]->id;
+		/* update ref if it was in the cache */
 		switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
-                        env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
-			LDNS_RR_TYPE_NS && !pside)?0:leeway))) {
+				env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
+				LDNS_RR_TYPE_NS && !pside)?0:leeway))) {
 		case 0: /* ref unchanged, item inserted */
 			break;
 		case 2: /* ref updated, cache is superior */
@@ -103,9 +105,9 @@
 			 * the fallthrough warning */
 			/* fallthrough */
 		case 1: /* ref updated, item inserted */
-                        rep->rrsets[i] = rep->ref[i].key;
+			rep->rrsets[i] = rep->ref[i].key;
 		}
-        }
+	}
 }
 
 /** delete message from message cache */
@@ -271,7 +273,7 @@
 		akey = rrset_cache_lookup(env->rrset_cache, ns->name, 
 			ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
 		if(akey) {
-			if(!delegpt_add_rrset_A(dp, region, akey, 0)) {
+			if(!delegpt_add_rrset_A(dp, region, akey, 0, NULL)) {
 				lock_rw_unlock(&akey->entry.lock);
 				return 0;
 			}
@@ -291,7 +293,7 @@
 		akey = rrset_cache_lookup(env->rrset_cache, ns->name, 
 			ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
 		if(akey) {
-			if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) {
+			if(!delegpt_add_rrset_AAAA(dp, region, akey, 0, NULL)) {
 				lock_rw_unlock(&akey->entry.lock);
 				return 0;
 			}
@@ -325,7 +327,8 @@
 		akey = rrset_cache_lookup(env->rrset_cache, ns->name, 
 			ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
 		if(akey) {
-			if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) {
+			if(!delegpt_add_rrset_A(dp, region, akey, ns->lame,
+				NULL)) {
 				lock_rw_unlock(&akey->entry.lock);
 				return 0;
 			}
@@ -345,7 +348,8 @@
 		akey = rrset_cache_lookup(env->rrset_cache, ns->name, 
 			ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
 		if(akey) {
-			if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) {
+			if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame,
+				NULL)) {
 				lock_rw_unlock(&akey->entry.lock);
 				return 0;
 			}
@@ -531,22 +535,41 @@
 }
 
 struct dns_msg*
-tomsg(struct module_env* env, struct query_info* q, struct reply_info* r, 
-	struct regional* region, time_t now, struct regional* scratch)
+tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
+	struct regional* region, time_t now, int allow_expired,
+	struct regional* scratch)
 {
 	struct dns_msg* msg;
 	size_t i;
-	if(now > r->ttl)
-		return NULL;
+	int is_expired = 0;
+	time_t now_control = now;
+	if(now > r->ttl) {
+		/* Check if we are allowed to serve expired */
+		if(allow_expired) {
+			if(env->cfg->serve_expired_ttl &&
+				r->serve_expired_ttl < now) {
+				return NULL;
+			}
+		} else {
+			return NULL;
+		}
+		/* Change the current time so we can pass the below TTL checks when
+		 * serving expired data. */
+		now_control = r->ttl - env->cfg->serve_expired_reply_ttl;
+		is_expired = 1;
+	}
+
 	msg = gen_dns_msg(region, q, r->rrset_count);
-	if(!msg)
-		return NULL;
+	if(!msg) return NULL;
 	msg->rep->flags = r->flags;
 	msg->rep->qdcount = r->qdcount;
-	msg->rep->ttl = r->ttl - now;
+	msg->rep->ttl = is_expired
+		?SERVE_EXPIRED_REPLY_TTL
+		:r->ttl - now;
 	if(r->prefetch_ttl > now)
 		msg->rep->prefetch_ttl = r->prefetch_ttl - now;
-	else	msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
+	else
+		msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
 	msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
 	msg->rep->security = r->security;
 	msg->rep->an_numrrsets = r->an_numrrsets;
@@ -553,9 +576,10 @@
 	msg->rep->ns_numrrsets = r->ns_numrrsets;
 	msg->rep->ar_numrrsets = r->ar_numrrsets;
 	msg->rep->rrset_count = r->rrset_count;
-        msg->rep->authoritative = r->authoritative;
-	if(!rrset_array_lock(r->ref, r->rrset_count, now))
+	msg->rep->authoritative = r->authoritative;
+	if(!rrset_array_lock(r->ref, r->rrset_count, now_control)) {
 		return NULL;
+	}
 	if(r->an_numrrsets > 0 && (r->rrsets[0]->rk.type == htons(
 		LDNS_RR_TYPE_CNAME) || r->rrsets[0]->rk.type == htons(
 		LDNS_RR_TYPE_DNAME)) && !reply_check_cname_chain(q, r)) {
@@ -569,7 +593,7 @@
 		return NULL;
 	}
 	for(i=0; i<msg->rep->rrset_count; i++) {
-		msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i], 
+		msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
 			region, now);
 		if(!msg->rep->rrsets[i]) {
 			rrset_array_unlock(r->ref, r->rrset_count);
@@ -721,6 +745,19 @@
 	int i, num=6; /* number of RR types to look up */
 	log_assert(lookup[num] == 0);
 
+	if(env->cfg->deny_any) {
+		/* return empty message */
+		msg = dns_msg_create(qname, qnamelen, qtype, qclass,
+			region, 0);
+		if(!msg) {
+			return NULL;
+		}
+		/* set NOTIMPL for RFC 8482 */
+		msg->rep->flags |= LDNS_RCODE_NOTIMPL;
+		msg->rep->security = sec_status_indeterminate;
+		return msg;
+	}
+
 	for(i=0; i<num; i++) {
 		/* look up this RR for inclusion in type ANY response */
 		struct ub_packed_rrset_key* rrset = rrset_cache_lookup(
@@ -783,7 +820,7 @@
 	if(e) {
 		struct msgreply_entry* key = (struct msgreply_entry*)e->key;
 		struct reply_info* data = (struct reply_info*)e->data;
-		struct dns_msg* msg = tomsg(env, &key->key, data, region, now, 
+		struct dns_msg* msg = tomsg(env, &key->key, data, region, now, 0,
 			scratch);
 		if(msg) {
 			lock_rw_unlock(&e->lock);
@@ -885,34 +922,38 @@
 	 * Empty nonterminals are NOERROR, so an NXDOMAIN for foo
 	 * means bla.foo also does not exist.  The DNSSEC proofs are
 	 * the same.  We search upwards for NXDOMAINs. */
-	if(env->cfg->harden_below_nxdomain)
-	    while(!dname_is_root(k.qname)) {
-		dname_remove_label(&k.qname, &k.qname_len);
-		h = query_info_hash(&k, flags);
-		e = slabhash_lookup(env->msg_cache, h, &k, 0);
-		if(!e && k.qtype != LDNS_RR_TYPE_A &&
-			env->cfg->qname_minimisation) {
-			k.qtype = LDNS_RR_TYPE_A;
+	if(env->cfg->harden_below_nxdomain) {
+		while(!dname_is_root(k.qname)) {
+			dname_remove_label(&k.qname, &k.qname_len);
 			h = query_info_hash(&k, flags);
 			e = slabhash_lookup(env->msg_cache, h, &k, 0);
-		}
-		if(e) {
-			struct reply_info* data = (struct reply_info*)e->data;
-			struct dns_msg* msg;
-			if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
-			  && data->security == sec_status_secure
-			  && (msg=tomsg(env, &k, data, region, now, scratch))){
+			if(!e && k.qtype != LDNS_RR_TYPE_A &&
+				env->cfg->qname_minimisation) {
+				k.qtype = LDNS_RR_TYPE_A;
+				h = query_info_hash(&k, flags);
+				e = slabhash_lookup(env->msg_cache, h, &k, 0);
+			}
+			if(e) {
+				struct reply_info* data = (struct reply_info*)e->data;
+				struct dns_msg* msg;
+				if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
+					&& data->security == sec_status_secure
+					&& (data->an_numrrsets == 0 ||
+						ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME)
+					&& (msg=tomsg(env, &k, data, region, now, 0, scratch))) {
+					lock_rw_unlock(&e->lock);
+					msg->qinfo.qname=qname;
+					msg->qinfo.qname_len=qnamelen;
+					/* check that DNSSEC really works out */
+					msg->rep->security = sec_status_unchecked;
+					iter_scrub_nxdomain(msg);
+					return msg;
+				}
 				lock_rw_unlock(&e->lock);
-				msg->qinfo.qname=qname;
-				msg->qinfo.qname_len=qnamelen;
-				/* check that DNSSEC really works out */
-				msg->rep->security = sec_status_unchecked;
-				return msg;
 			}
-			lock_rw_unlock(&e->lock);
+			k.qtype = qtype;
 		}
-		k.qtype = qtype;
-	    }
+	}
 
 	/* fill common RR types for ANY response to avoid requery */
 	if(qtype == LDNS_RR_TYPE_ANY) {
--- contrib/unbound/services/cache/dns.h.orig
+++ contrib/unbound/services/cache/dns.h
@@ -143,11 +143,14 @@
  * @param r: reply info that, together with qname, will make up the dns message.
  * @param region: where to allocate dns message.
  * @param now: the time now, for check if TTL on cache entry is ok.
+ * @param allow_expired: if true and serve-expired is enabled, it will allow
+ *	for expired dns_msg to be generated based on the configured serve-expired
+ *	logic.
  * @param scratch: where to allocate temporary data.
  * */
 struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
 	struct reply_info* r, struct regional* region, time_t now,
-	struct regional* scratch);
+	int allow_expired, struct regional* scratch);
 
 /** 
  * Find cached message 
@@ -160,7 +163,7 @@
  * @param region: where to allocate result.
  * @param scratch: where to allocate temporary data.
  * @param no_partial: if true, only complete messages and not a partial
- *   one (with only the start of the CNAME chain and not the rest).
+ *	one (with only the start of the CNAME chain and not the rest).
  * @return new response message (alloced in region, rrsets do not have IDs).
  * 	or NULL on error or if not found in cache.
  *	TTLs are made relative to the current time.
--- contrib/unbound/services/cache/infra.c.orig
+++ contrib/unbound/services/cache/infra.c
@@ -41,6 +41,8 @@
 #include "config.h"
 #include "sldns/rrdef.h"
 #include "sldns/str2wire.h"
+#include "sldns/sbuffer.h"
+#include "sldns/wire2str.h"
 #include "services/cache/infra.h"
 #include "util/storage/slabhash.h"
 #include "util/storage/lookup3.h"
@@ -907,7 +909,8 @@
 }
 
 int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
-	size_t namelen, time_t timenow)
+	size_t namelen, time_t timenow, struct query_info* qinfo,
+	struct comm_reply* replylist)
 {
 	int lim, max;
 	struct lruhash_entry* entry;
@@ -930,9 +933,19 @@
 		lock_rw_unlock(&entry->lock);
 
 		if(premax < lim && max >= lim) {
-			char buf[257];
+			char buf[257], qnm[257], ts[12], cs[12], ip[128];
 			dname_str(name, buf);
-			verbose(VERB_OPS, "ratelimit exceeded %s %d", buf, lim);
+			dname_str(qinfo->qname, qnm);
+			sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts));
+			sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
+			ip[0]=0;
+			if(replylist) {
+				addr_to_str((struct sockaddr_storage *)&replylist->addr,
+					replylist->addrlen, ip, sizeof(ip));
+				verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
+			} else {
+				verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
+			}
 		}
 		return (max < lim);
 	}
@@ -991,7 +1004,7 @@
 }
 
 int infra_ip_ratelimit_inc(struct infra_cache* infra,
-  struct comm_reply* repinfo, time_t timenow)
+  struct comm_reply* repinfo, time_t timenow, struct sldns_buffer* buffer)
 {
 	int max;
 	struct lruhash_entry* entry;
@@ -1010,11 +1023,28 @@
 		lock_rw_unlock(&entry->lock);
 
 		if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {
-			char client_ip[128];
+			char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
 			addr_to_str((struct sockaddr_storage *)&repinfo->addr,
 				repinfo->addrlen, client_ip, sizeof(client_ip));
-			verbose(VERB_OPS, "ip_ratelimit exceeded %s %d",
-				client_ip, infra_ip_ratelimit);
+			qnm[0]=0;
+			if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
+				LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
+				(void)sldns_wire2str_rrquestion_buf(
+					sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
+					sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
+					qnm, sizeof(qnm));
+				if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
+					qnm[strlen(qnm)-1] = 0; /*remove newline*/
+				if(strchr(qnm, '\t'))
+					*strchr(qnm, '\t') = ' ';
+				if(strchr(qnm, '\t'))
+					*strchr(qnm, '\t') = ' ';
+				verbose(VERB_OPS, "ip_ratelimit exceeded %s %d %s",
+					client_ip, infra_ip_ratelimit, qnm);
+			} else {
+				verbose(VERB_OPS, "ip_ratelimit exceeded %s %d (no query name)",
+					client_ip, infra_ip_ratelimit);
+			}
 		}
 		return (max <= infra_ip_ratelimit);
 	}
--- contrib/unbound/services/cache/infra.h.orig
+++ contrib/unbound/services/cache/infra.h
@@ -366,12 +366,15 @@
  * @param name: zone name
  * @param namelen: zone name length
  * @param timenow: what time it is now.
+ * @param qinfo: for logging, query name.
+ * @param replylist: for logging, querier's address (if any).
  * @return 1 if it could be incremented. 0 if the increment overshot the
  * ratelimit or if in the previous second the ratelimit was exceeded.
  * Failures like alloc failures are not returned (probably as 1).
  */
 int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
-	size_t namelen, time_t timenow);
+	size_t namelen, time_t timenow, struct query_info* qinfo,
+	struct comm_reply* replylist);
 
 /**
  * Decrement the query rate counter for a delegation point.
@@ -410,10 +413,12 @@
  *  @param infra: infra cache
  *  @param repinfo: information about client
  *  @param timenow: what time it is now.
+ *  @param buffer: with query for logging.
  *  @return 1 if it could be incremented. 0 if the increment overshot the
  *  ratelimit and the query should be dropped. */
 int infra_ip_ratelimit_inc(struct infra_cache* infra,
-	struct comm_reply* repinfo, time_t timenow);
+	struct comm_reply* repinfo, time_t timenow,
+	struct sldns_buffer* buffer);
 
 /**
  * Get memory used by the infra cache.
--- contrib/unbound/services/listen_dnsport.c.orig
+++ contrib/unbound/services/listen_dnsport.c
@@ -53,6 +53,9 @@
 #include "util/config_file.h"
 #include "util/net_help.h"
 #include "sldns/sbuffer.h"
+#include "services/mesh.h"
+#include "util/fptr_wlist.h"
+#include "util/locks.h"
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -70,6 +73,18 @@
 /** number of queued TCP connections for listen() */
 #define TCP_BACKLOG 256 
 
+/** number of simultaneous requests a client can have */
+#define TCP_MAX_REQ_SIMULTANEOUS 32
+
+#ifndef THREADS_DISABLED
+/** lock on the counter of stream buffer memory */
+static lock_basic_type stream_wait_count_lock;
+#endif
+/** size (in bytes) of stream wait buffers */
+static size_t stream_wait_count = 0;
+/** is the lock initialised for stream wait buffers */
+static int stream_wait_lock_inited = 0;
+
 /**
  * Debug print of the getaddrinfo returned address.
  * @param addr: the address returned.
@@ -247,6 +262,26 @@
 		}
 #endif /* SO_REUSEADDR */
 #ifdef SO_REUSEPORT
+#  ifdef SO_REUSEPORT_LB
+		/* on FreeBSD 12 we have SO_REUSEPORT_LB that does loadbalance
+		 * like SO_REUSEPORT on Linux.  This is what the users want
+		 * with the config option in unbound.conf; if we actually
+		 * need local address and port reuse they'll also need to
+		 * have SO_REUSEPORT set for them, assume it was _LB they want.
+		 */
+		if (reuseport && *reuseport &&
+		    setsockopt(s, SOL_SOCKET, SO_REUSEPORT_LB, (void*)&on,
+			(socklen_t)sizeof(on)) < 0) {
+#ifdef ENOPROTOOPT
+			if(errno != ENOPROTOOPT || verbosity >= 3)
+				log_warn("setsockopt(.. SO_REUSEPORT_LB ..) failed: %s",
+					strerror(errno));
+#endif
+			/* this option is not essential, we can continue */
+			*reuseport = 0;
+		}
+#  else /* no SO_REUSEPORT_LB */
+
 		/* try to set SO_REUSEPORT so that incoming
 		 * queries are distributed evenly among the receiving threads.
 		 * Each thread must have its own socket bound to the same port,
@@ -263,6 +298,7 @@
 			/* this option is not essential, we can continue */
 			*reuseport = 0;
 		}
+#  endif /* SO_REUSEPORT_LB */
 #else
 		(void)reuseport;
 #endif /* defined(SO_REUSEPORT) */
@@ -565,7 +601,11 @@
 		if(family==AF_INET6 && errno==EINVAL)
 			*noproto = 1;
 		else if(errno != EADDRINUSE &&
-			!(errno == EACCES && verbosity < 4 && !listen)) {
+			!(errno == EACCES && verbosity < 4 && !listen)
+#ifdef EADDRNOTAVAIL
+			&& !(errno == EADDRNOTAVAIL && verbosity < 4 && !listen)
+#endif
+			) {
 			log_err_addr("can't bind socket", strerror(errno),
 				(struct sockaddr_storage*)addr, addrlen);
 		}
@@ -811,9 +851,16 @@
 #ifdef ENOPROTOOPT
 		/* squelch ENOPROTOOPT: freebsd server mode with kernel support
 		   disabled, except when verbosity enabled for debugging */
-		if(errno != ENOPROTOOPT || verbosity >= 3)
+		if(errno != ENOPROTOOPT || verbosity >= 3) {
 #endif
-		  log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
+		  if(errno == EPERM) {
+		  	log_warn("Setting TCP Fast Open as server failed: %s ; this could likely be because sysctl net.inet.tcp.fastopen.enabled, net.inet.tcp.fastopen.server_enable, or net.ipv4.tcp_fastopen is disabled", strerror(errno));
+		  } else {
+		  	log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
+		  }
+#ifdef ENOPROTOOPT
+		}
+#endif
 	}
 #endif
 	return s;
@@ -1235,6 +1282,10 @@
 		free(front);
 		return NULL;
 	}
+	if(!stream_wait_lock_inited) {
+		lock_basic_init(&stream_wait_count_lock);
+		stream_wait_lock_inited = 1;
+	}
 
 	/* create comm points as needed */
 	while(ports) {
@@ -1247,11 +1298,13 @@
 				ports->ftype == listen_type_tcp_dnscrypt)
 			cp = comm_point_create_tcp(base, ports->fd, 
 				tcp_accept_count, tcp_idle_timeout,
-				tcp_conn_limit, bufsize, cb, cb_arg);
+				tcp_conn_limit, bufsize, front->udp_buff,
+				cb, cb_arg);
 		else if(ports->ftype == listen_type_ssl) {
 			cp = comm_point_create_tcp(base, ports->fd, 
 				tcp_accept_count, tcp_idle_timeout,
-				tcp_conn_limit, bufsize, cb, cb_arg);
+				tcp_conn_limit, bufsize, front->udp_buff,
+				cb, cb_arg);
 			cp->ssl = sslctx;
 		} else if(ports->ftype == listen_type_udpancil ||
 				  ports->ftype == listen_type_udpancil_dnscrypt)
@@ -1322,6 +1375,10 @@
 #endif
 	sldns_buffer_free(front->udp_buff);
 	free(front);
+	if(stream_wait_lock_inited) {
+		stream_wait_lock_inited = 0;
+		lock_basic_destroy(&stream_wait_count_lock);
+	}
 }
 
 struct listen_port* 
@@ -1479,3 +1536,373 @@
 	}
 }
 
+struct tcp_req_info*
+tcp_req_info_create(struct sldns_buffer* spoolbuf)
+{
+	struct tcp_req_info* req = (struct tcp_req_info*)malloc(sizeof(*req));
+	if(!req) {
+		log_err("malloc failure for new stream outoforder processing structure");
+		return NULL;
+	}
+	memset(req, 0, sizeof(*req));
+	req->spool_buffer = spoolbuf;
+	return req;
+}
+
+void
+tcp_req_info_delete(struct tcp_req_info* req)
+{
+	if(!req) return;
+	tcp_req_info_clear(req);
+	/* cp is pointer back to commpoint that owns this struct and
+	 * called delete on us */
+	/* spool_buffer is shared udp buffer, not deleted here */
+	free(req);
+}
+
+void tcp_req_info_clear(struct tcp_req_info* req)
+{
+	struct tcp_req_open_item* open, *nopen;
+	struct tcp_req_done_item* item, *nitem;
+	if(!req) return;
+
+	/* free outstanding request mesh reply entries */
+	open = req->open_req_list;
+	while(open) {
+		nopen = open->next;
+		mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp);
+		free(open);
+		open = nopen;
+	}
+	req->open_req_list = NULL;
+	req->num_open_req = 0;
+	
+	/* free pending writable result packets */
+	item = req->done_req_list;
+	while(item) {
+		nitem = item->next;
+		lock_basic_lock(&stream_wait_count_lock);
+		stream_wait_count -= (sizeof(struct tcp_req_done_item)
+			+item->len);
+		lock_basic_unlock(&stream_wait_count_lock);
+		free(item->buf);
+		free(item);
+		item = nitem;
+	}
+	req->done_req_list = NULL;
+	req->num_done_req = 0;
+	req->read_is_closed = 0;
+}
+
+void
+tcp_req_info_remove_mesh_state(struct tcp_req_info* req, struct mesh_state* m)
+{
+	struct tcp_req_open_item* open, *prev = NULL;
+	if(!req || !m) return;
+	open = req->open_req_list;
+	while(open) {
+		if(open->mesh_state == m) {
+			struct tcp_req_open_item* next;
+			if(prev) prev->next = open->next;
+			else req->open_req_list = open->next;
+			/* caller has to manage the mesh state reply entry */
+			next = open->next;
+			free(open);
+			req->num_open_req --;
+
+			/* prev = prev; */
+			open = next;
+			continue;
+		}
+		prev = open;
+		open = open->next;
+	}
+}
+
+/** setup listening for read or write */
+static void
+tcp_req_info_setup_listen(struct tcp_req_info* req)
+{
+	int wr = 0;
+	int rd = 0;
+
+	if(req->cp->tcp_byte_count != 0) {
+		/* cannot change, halfway through */
+		return;
+	}
+
+	if(!req->cp->tcp_is_reading)
+		wr = 1;
+	if(req->num_open_req + req->num_done_req < TCP_MAX_REQ_SIMULTANEOUS &&
+		!req->read_is_closed)
+		rd = 1;
+	
+	if(wr) {
+		req->cp->tcp_is_reading = 0;
+		comm_point_stop_listening(req->cp);
+		comm_point_start_listening(req->cp, -1,
+			req->cp->tcp_timeout_msec);
+	} else if(rd) {
+		req->cp->tcp_is_reading = 1;
+		comm_point_stop_listening(req->cp);
+		comm_point_start_listening(req->cp, -1,
+			req->cp->tcp_timeout_msec);
+		/* and also read it (from SSL stack buffers), so
+		 * no event read event is expected since the remainder of
+		 * the TLS frame is sitting in the buffers. */
+		req->read_again = 1;
+	} else {
+		comm_point_stop_listening(req->cp);
+		comm_point_start_listening(req->cp, -1,
+			req->cp->tcp_timeout_msec);
+		comm_point_listen_for_rw(req->cp, 0, 0);
+	}
+}
+
+/** remove first item from list of pending results */
+static struct tcp_req_done_item*
+tcp_req_info_pop_done(struct tcp_req_info* req)
+{
+	struct tcp_req_done_item* item;
+	log_assert(req->num_done_req > 0 && req->done_req_list);
+	item = req->done_req_list;
+	lock_basic_lock(&stream_wait_count_lock);
+	stream_wait_count -= (sizeof(struct tcp_req_done_item)+item->len);
+	lock_basic_unlock(&stream_wait_count_lock);
+	req->done_req_list = req->done_req_list->next;
+	req->num_done_req --;
+	return item;
+}
+
+/** Send given buffer and setup to write */
+static void
+tcp_req_info_start_write_buf(struct tcp_req_info* req, uint8_t* buf,
+	size_t len)
+{
+	sldns_buffer_clear(req->cp->buffer);
+	sldns_buffer_write(req->cp->buffer, buf, len);
+	sldns_buffer_flip(req->cp->buffer);
+
+	req->cp->tcp_is_reading = 0; /* we are now writing */
+}
+
+/** pick up the next result and start writing it to the channel */
+static void
+tcp_req_pickup_next_result(struct tcp_req_info* req)
+{
+	if(req->num_done_req > 0) {
+		/* unlist the done item from the list of pending results */
+		struct tcp_req_done_item* item = tcp_req_info_pop_done(req);
+		tcp_req_info_start_write_buf(req, item->buf, item->len);
+		free(item->buf);
+		free(item);
+	}
+}
+
+/** the read channel has closed */
+int
+tcp_req_info_handle_read_close(struct tcp_req_info* req)
+{
+	verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd);
+	/* reset byte count for (potential) partial read */
+	req->cp->tcp_byte_count = 0;
+	/* if we still have results to write, pick up next and write it */
+	if(req->num_done_req != 0) {
+		tcp_req_pickup_next_result(req);
+		tcp_req_info_setup_listen(req);
+		return 1;
+	}
+	/* if nothing to do, this closes the connection */
+	if(req->num_open_req == 0 && req->num_done_req == 0)
+		return 0;
+	/* otherwise, we must be waiting for dns resolve, wait with timeout */
+	req->read_is_closed = 1;
+	tcp_req_info_setup_listen(req);
+	return 1;
+}
+
+void
+tcp_req_info_handle_writedone(struct tcp_req_info* req)
+{
+	/* back to reading state, we finished this write event */
+	sldns_buffer_clear(req->cp->buffer);
+	if(req->num_done_req == 0 && req->read_is_closed) {
+		/* no more to write and nothing to read, close it */
+		comm_point_drop_reply(&req->cp->repinfo);
+		return;
+	}
+	req->cp->tcp_is_reading = 1;
+	/* see if another result needs writing */
+	tcp_req_pickup_next_result(req);
+
+	/* see if there is more to write, if not stop_listening for writing */
+	/* see if new requests are allowed, if so, start_listening
+	 * for reading */
+	tcp_req_info_setup_listen(req);
+}
+
+void
+tcp_req_info_handle_readdone(struct tcp_req_info* req)
+{
+	struct comm_point* c = req->cp;
+
+	/* we want to read up several requests, unless there are
+	 * pending answers */
+
+	req->is_drop = 0;
+	req->is_reply = 0;
+	req->in_worker_handle = 1;
+	sldns_buffer_set_limit(req->spool_buffer, 0);
+	/* handle the current request */
+	/* this calls the worker handle request routine that could give
+	 * a cache response, or localdata response, or drop the reply,
+	 * or schedule a mesh entry for later */
+	fptr_ok(fptr_whitelist_comm_point(c->callback));
+	if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
+		req->in_worker_handle = 0;
+		/* there is an answer, put it up.  It is already in the
+		 * c->buffer, just send it. */
+		/* since we were just reading a query, the channel is
+		 * clear to write to */
+	send_it:
+		c->tcp_is_reading = 0;
+		comm_point_stop_listening(c);
+		comm_point_start_listening(c, -1, c->tcp_timeout_msec);
+		return;
+	}
+	req->in_worker_handle = 0;
+	/* it should be waiting in the mesh for recursion.
+	 * If mesh failed to add a new entry and called commpoint_drop_reply. 
+	 * Then the mesh state has been cleared. */
+	if(req->is_drop) {
+		/* the reply has been dropped, stream has been closed. */
+		return;
+	}
+	/* If mesh failed(mallocfail) and called commpoint_send_reply with
+	 * something like servfail then we pick up that reply below. */
+	if(req->is_reply) {
+		goto send_it;
+	}
+
+	sldns_buffer_clear(c->buffer);
+	/* if pending answers, pick up an answer and start sending it */
+	tcp_req_pickup_next_result(req);
+
+	/* if answers pending, start sending answers */
+	/* read more requests if we can have more requests */
+	tcp_req_info_setup_listen(req);
+}
+
+int
+tcp_req_info_add_meshstate(struct tcp_req_info* req,
+	struct mesh_area* mesh, struct mesh_state* m)
+{
+	struct tcp_req_open_item* item;
+	log_assert(req && mesh && m);
+	item = (struct tcp_req_open_item*)malloc(sizeof(*item));
+	if(!item) return 0;
+	item->next = req->open_req_list;
+	item->mesh = mesh;
+	item->mesh_state = m;
+	req->open_req_list = item;
+	req->num_open_req++;
+	return 1;
+}
+
+/** Add a result to the result list.  At the end. */
+static int
+tcp_req_info_add_result(struct tcp_req_info* req, uint8_t* buf, size_t len)
+{
+	struct tcp_req_done_item* last = NULL;
+	struct tcp_req_done_item* item;
+	size_t space;
+
+	/* see if we have space */
+	space = sizeof(struct tcp_req_done_item) + len;
+	lock_basic_lock(&stream_wait_count_lock);
+	if(stream_wait_count + space > stream_wait_max) {
+		lock_basic_unlock(&stream_wait_count_lock);
+		verbose(VERB_ALGO, "drop stream reply, no space left, in stream-wait-size");
+		return 0;
+	}
+	stream_wait_count += space;
+	lock_basic_unlock(&stream_wait_count_lock);
+
+	/* find last element */
+	last = req->done_req_list;
+	while(last && last->next)
+		last = last->next;
+	
+	/* create new element */
+	item = (struct tcp_req_done_item*)malloc(sizeof(*item));
+	if(!item) {
+		log_err("malloc failure, for stream result list");
+		return 0;
+	}
+	item->next = NULL;
+	item->len = len;
+	item->buf = memdup(buf, len);
+	if(!item->buf) {
+		free(item);
+		log_err("malloc failure, adding reply to stream result list");
+		return 0;
+	}
+
+	/* link in */
+	if(last) last->next = item;
+	else req->done_req_list = item;
+	req->num_done_req++;
+	return 1;
+}
+
+void
+tcp_req_info_send_reply(struct tcp_req_info* req)
+{
+	if(req->in_worker_handle) {
+		/* reply from mesh is in the spool_buffer */
+		/* copy now, so that the spool buffer is free for other tasks
+		 * before the callback is done */
+		sldns_buffer_clear(req->cp->buffer);
+		sldns_buffer_write(req->cp->buffer,
+			sldns_buffer_begin(req->spool_buffer),
+			sldns_buffer_limit(req->spool_buffer));
+		sldns_buffer_flip(req->cp->buffer);
+		req->is_reply = 1;
+		return;
+	}
+	/* now that the query has been handled, that mesh_reply entry
+	 * should be removed, from the tcp_req_info list,
+	 * the mesh state cleanup removes then with region_cleanup and
+	 * replies_sent true. */
+	/* see if we can send it straight away (we are not doing
+	 * anything else).  If so, copy to buffer and start */
+	if(req->cp->tcp_is_reading && req->cp->tcp_byte_count == 0) {
+		/* buffer is free, and was ready to read new query into,
+		 * but we are now going to use it to send this answer */
+		tcp_req_info_start_write_buf(req,
+			sldns_buffer_begin(req->spool_buffer),
+			sldns_buffer_limit(req->spool_buffer));
+		/* switch to listen to write events */
+		comm_point_stop_listening(req->cp);
+		comm_point_start_listening(req->cp, -1,
+			req->cp->tcp_timeout_msec);
+		return;
+	}
+	/* queue up the answer behind the others already pending */
+	if(!tcp_req_info_add_result(req, sldns_buffer_begin(req->spool_buffer),
+		sldns_buffer_limit(req->spool_buffer))) {
+		/* drop the connection, we are out of resources */
+		comm_point_drop_reply(&req->cp->repinfo);
+	}
+}
+
+size_t tcp_req_info_get_stream_buffer_size(void)
+{
+	size_t s;
+	if(!stream_wait_lock_inited)
+		return stream_wait_count;
+	lock_basic_lock(&stream_wait_count_lock);
+	s = stream_wait_count;
+	lock_basic_unlock(&stream_wait_count_lock);
+	return s;
+}
--- contrib/unbound/services/listen_dnsport.h.orig
+++ contrib/unbound/services/listen_dnsport.h
@@ -237,4 +237,134 @@
  */
 int create_local_accept_sock(const char* path, int* noproto, int use_systemd);
 
+/**
+ * TCP request info.  List of requests outstanding on the channel, that
+ * are asked for but not yet answered back.
+ */
+struct tcp_req_info {
+	/** the TCP comm point for this.  Its buffer is used for read/write */
+	struct comm_point* cp;
+	/** the buffer to use to spool reply from mesh into,
+	 * it can then be copied to the result list and written.
+	 * it is a pointer to the shared udp buffer. */
+	struct sldns_buffer* spool_buffer;
+	/** are we in worker_handle function call (for recursion callback)*/
+	int in_worker_handle;
+	/** is the comm point dropped (by worker handle).
+	 * That means we have to disconnect the channel. */
+	int is_drop;
+	/** is the comm point set to send_reply (by mesh new client in worker
+	 * handle), if so answer is available in c.buffer */
+	int is_reply;
+	/** read channel has closed, just write pending results */
+	int read_is_closed;
+	/** read again */
+	int read_again;
+	/** number of outstanding requests */
+	int num_open_req;
+	/** list of outstanding requests */
+	struct tcp_req_open_item* open_req_list;
+	/** number of pending writeable results */
+	int num_done_req;
+	/** list of pending writable result packets, malloced one at a time */
+	struct tcp_req_done_item* done_req_list;
+};
+
+/**
+ * List of open items in TCP channel
+ */
+struct tcp_req_open_item {
+	/** next in list */
+	struct tcp_req_open_item* next;
+	/** the mesh area of the mesh_state */
+	struct mesh_area* mesh;
+	/** the mesh state */
+	struct mesh_state* mesh_state;
+};
+
+/**
+ * List of done items in TCP channel
+ */
+struct tcp_req_done_item {
+	/** next in list */
+	struct tcp_req_done_item* next;
+	/** the buffer with packet contents */
+	uint8_t* buf;
+	/** length of the buffer */
+	size_t len;
+};
+
+/**
+ * Create tcp request info structure that keeps track of open
+ * requests on the TCP channel that are resolved at the same time,
+ * and the pending results that have to get written back to that client.
+ * @param spoolbuf: shared buffer
+ * @return new structure or NULL on alloc failure.
+ */
+struct tcp_req_info* tcp_req_info_create(struct sldns_buffer* spoolbuf);
+
+/**
+ * Delete tcp request structure.  Called by owning commpoint.
+ * Removes mesh entry references and stored results from the lists.
+ * @param req: the tcp request info
+ */
+void tcp_req_info_delete(struct tcp_req_info* req);
+
+/**
+ * Clear tcp request structure.  Removes list entries, sets it up ready
+ * for the next connection.
+ * @param req: tcp request info structure.
+ */
+void tcp_req_info_clear(struct tcp_req_info* req);
+
+/**
+ * Remove mesh state entry from list in tcp_req_info.
+ * caller has to manage the mesh state reply entry in the mesh state.
+ * @param req: the tcp req info that has the entry removed from the list.
+ * @param m: the state removed from the list.
+ */
+void tcp_req_info_remove_mesh_state(struct tcp_req_info* req,
+	struct mesh_state* m);
+
+/**
+ * Handle write done of the last result packet
+ * @param req: the tcp req info.
+ */
+void tcp_req_info_handle_writedone(struct tcp_req_info* req);
+
+/**
+ * Handle read done of a new request from the client
+ * @param req: the tcp req info.
+ */
+void tcp_req_info_handle_readdone(struct tcp_req_info* req);
+
+/**
+ * Add mesh state to the tcp req list of open requests.
+ * So the comm_reply can be removed off the mesh reply list when
+ * the tcp channel has to be closed (for other reasons then that that
+ * request was done, eg. channel closed by client or some format error).
+ * @param req: tcp req info structure.  It keeps track of the simultaneous
+ * 	requests and results on a tcp (or TLS) channel.
+ * @param mesh: mesh area for the state.
+ * @param m: mesh state to add.
+ * @return 0 on failure (malloc failure).
+ */
+int tcp_req_info_add_meshstate(struct tcp_req_info* req,
+	struct mesh_area* mesh, struct mesh_state* m);
+
+/**
+ * Send reply on tcp simultaneous answer channel.  May queue it up.
+ * @param req: request info structure.
+ */
+void tcp_req_info_send_reply(struct tcp_req_info* req);
+
+/** the read channel has closed
+ * @param req: request. remaining queries are looked up and answered. 
+ * @return zero if nothing to do, just close the tcp.
+ */
+int tcp_req_info_handle_read_close(struct tcp_req_info* req);
+
+/** get the size of currently used tcp stream wait buffers (in bytes) */
+size_t tcp_req_info_get_stream_buffer_size(void);
+
 #endif /* LISTEN_DNSPORT_H */
--- contrib/unbound/services/localzone.c.orig
+++ contrib/unbound/services/localzone.c
@@ -41,7 +41,6 @@
 #include "config.h"
 #include "services/localzone.h"
 #include "sldns/str2wire.h"
-#include "sldns/sbuffer.h"
 #include "util/regional.h"
 #include "util/config_file.h"
 #include "util/data/dname.h"
@@ -395,10 +394,31 @@
 	return 1;
 }
 
-/** find a data node by exact name */
-static struct local_data* 
-lz_find_node(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
+/** Delete RR from local-zone RRset, wastes memory as the deleted RRs cannot be
+ * free'd (regionally alloc'd) */
+int
+local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index)
 {
+	log_assert(pd->count > 0);
+	if(index >= pd->count) {
+		log_warn("Trying to remove RR with out of bound index");
+		return 0;
+	}
+	if(index + 1 < pd->count) {
+		/* not removing last element */
+		size_t nexti = index + 1;
+		size_t num = pd->count - nexti;
+		memmove(pd->rr_len+index, pd->rr_len+nexti, sizeof(*pd->rr_len)*num);
+		memmove(pd->rr_ttl+index, pd->rr_ttl+nexti, sizeof(*pd->rr_ttl)*num);
+		memmove(pd->rr_data+index, pd->rr_data+nexti, sizeof(*pd->rr_data)*num);
+	}
+	pd->count--;
+	return 1;
+}
+
+struct local_data* 
+local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
+{
 	struct local_data key;
 	key.node.key = &key;
 	key.name = nm;
@@ -412,7 +432,7 @@
 lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen, 
 	int nmlabs, struct local_data** res)
 {
-	struct local_data* ld = lz_find_node(z, nm, nmlen, nmlabs);
+	struct local_data* ld = local_zone_find_data(z, nm, nmlen, nmlabs);
 	if(!ld) {
 		/* create a domain name to store rr. */
 		ld = (struct local_data*)regional_alloc_zero(z->region,
@@ -443,45 +463,24 @@
 	return 1;
 }
 
-/** enter data RR into auth zone */
-static int
-lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
+int
+local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
+	int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
+	uint8_t* rdata, size_t rdata_len, const char* rrstr)
 {
-	uint8_t* nm;
-	size_t nmlen;
-	int nmlabs;
 	struct local_data* node;
 	struct local_rrset* rrset;
 	struct packed_rrset_data* pd;
-	uint16_t rrtype = 0, rrclass = 0;
-	time_t ttl = 0;
-	uint8_t rr[LDNS_RR_BUF_SIZE];
-	uint8_t* rdata;
-	size_t rdata_len;
-	if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
-		sizeof(rr), &rdata, &rdata_len)) {
-		log_err("bad local-data: %s", rrstr);
-		return 0;
-	}
-	log_assert(z->dclass == rrclass);
-	if(z->type == local_zone_redirect &&
-		query_dname_compare(z->name, nm) != 0) {
-		log_err("local-data in redirect zone must reside at top of zone"
-			", not at %s", rrstr);
-		free(nm);
-		return 0;
-	}
-	nmlabs = dname_count_size_labels(nm, &nmlen);
+
 	if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
-		free(nm);
 		return 0;
 	}
 	log_assert(node);
-	free(nm);
 
 	/* Reject it if we would end up having CNAME and other data (including
 	 * another CNAME) for a redirect zone. */
-	if(z->type == local_zone_redirect && node->rrsets) {
+	if((z->type == local_zone_redirect ||
+		z->type == local_zone_inform_redirect) && node->rrsets) {
 		const char* othertype = NULL;
 		if (rrtype == LDNS_RR_TYPE_CNAME)
 			othertype = "other";
@@ -518,6 +517,39 @@
 	return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
 }
 
+/** enter data RR into auth zone */
+int
+lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
+{
+	uint8_t* nm;
+	size_t nmlen;
+	int nmlabs, ret;
+	uint16_t rrtype = 0, rrclass = 0;
+	time_t ttl = 0;
+	uint8_t rr[LDNS_RR_BUF_SIZE];
+	uint8_t* rdata;
+	size_t rdata_len;
+	if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
+		sizeof(rr), &rdata, &rdata_len)) {
+		log_err("bad local-data: %s", rrstr);
+		return 0;
+	}
+	log_assert(z->dclass == rrclass);
+	if((z->type == local_zone_redirect ||
+		z->type == local_zone_inform_redirect) &&
+		query_dname_compare(z->name, nm) != 0) {
+		log_err("local-data in redirect zone must reside at top of zone"
+			", not at %s", rrstr);
+		free(nm);
+		return 0;
+	}
+	nmlabs = dname_count_size_labels(nm, &nmlen);
+	ret = local_zone_enter_rr(z, nm, nmlen, nmlabs, rrtype, rrclass, ttl,
+		rdata, rdata_len, rrstr);
+	free(nm);
+	return ret;
+}
+
 /** enter a data RR into auth data; a zone for it must exist */
 static int
 lz_enter_rr_str(struct local_zones* zones, const char* rr)
@@ -821,12 +853,12 @@
 		log_err("out of memory adding default zone");
 		return 0;
 	}
-	/* test. zone (RFC 7686) */
+	/* test. zone (RFC 6761) */
 	if(!add_empty_default(zones, cfg, "test.")) {
 		log_err("out of memory adding default zone");
 		return 0;
 	}
-	/* invalid. zone (RFC 7686) */
+	/* invalid. zone (RFC 6761) */
 	if(!add_empty_default(zones, cfg, "invalid.")) {
 		log_err("out of memory adding default zone");
 		return 0;
@@ -1111,6 +1143,22 @@
 	return (struct local_zone*)rbtree_search(&zones->ztree, &key);
 }
 
+struct local_zone*
+local_zones_find_le(struct local_zones* zones,
+        uint8_t* name, size_t len, int labs, uint16_t dclass,
+	int* exact)
+{
+	struct local_zone key;
+	rbnode_type *node;
+	key.node.key = &key;
+	key.dclass = dclass;
+	key.name = name;
+	key.namelen = len;
+	key.namelabs = labs;
+	*exact = rbtree_find_less_equal(&zones->ztree, &key, &node);
+	return (struct local_zone*)node;
+}
+
 /** print all RRsets in local zone */
 static void 
 local_zone_out(struct local_zone* z)
@@ -1119,7 +1167,7 @@
 	struct local_rrset* p;
 	RBTREE_FOR(d, struct local_data*, &z->data) {
 		for(p = d->rrsets; p; p = p->next) {
-			log_nametypeclass(0, "rrset", d->name, 
+			log_nametypeclass(NO_VERBOSE, "rrset", d->name,
 				ntohs(p->rrset->rk.type),
 				ntohs(p->rrset->rk.rrset_class));
 		}
@@ -1136,7 +1184,7 @@
 		lock_rw_rdlock(&z->lock);
 		snprintf(buf, sizeof(buf), "%s zone",
 			local_zone_type2str(z->type));
-		log_nametypeclass(0, buf, z->name, 0, z->dclass);
+		log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
 		local_zone_out(z);
 		lock_rw_unlock(&z->lock);
 	}
@@ -1307,8 +1355,7 @@
 	return result;
 }
 
-/** answer local data match */
-static int
+int
 local_data_answer(struct local_zone* z, struct module_env* env,
 	struct query_info* qinfo, struct edns_data* edns,
 	struct comm_reply* repinfo, sldns_buffer* buf,
@@ -1323,7 +1370,8 @@
 	key.name = qinfo->qname;
 	key.namelen = qinfo->qname_len;
 	key.namelabs = labs;
-	if(lz_type == local_zone_redirect) {
+	if(lz_type == local_zone_redirect ||
+		lz_type == local_zone_inform_redirect) {
 		key.name = z->name;
 		key.namelen = z->namelen;
 		key.namelabs = z->namelabs;
@@ -1355,22 +1403,77 @@
 		return 0;
 
 	/* Special case for alias matching.  See local_data_answer(). */
-	if(lz_type == local_zone_redirect &&
+	if((lz_type == local_zone_redirect ||
+		lz_type == local_zone_inform_redirect) &&
 		qinfo->qtype != LDNS_RR_TYPE_CNAME &&
 		lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
+		uint8_t* ctarget;
+		size_t ctargetlen = 0;
+
 		qinfo->local_alias =
 			regional_alloc_zero(temp, sizeof(struct local_rrset));
 		if(!qinfo->local_alias)
 			return 0; /* out of memory */
-		qinfo->local_alias->rrset =
-			regional_alloc_init(temp, lr->rrset, sizeof(*lr->rrset));
+		qinfo->local_alias->rrset = regional_alloc_init(
+			temp, lr->rrset, sizeof(*lr->rrset));
 		if(!qinfo->local_alias->rrset)
 			return 0; /* out of memory */
 		qinfo->local_alias->rrset->rk.dname = qinfo->qname;
 		qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
+		get_cname_target(lr->rrset, &ctarget, &ctargetlen);
+		if(!ctargetlen)
+			return 0; /* invalid cname */
+		if(dname_is_wild(ctarget)) {
+			/* synthesize cname target */
+			struct packed_rrset_data* d;
+			/* -3 for wildcard label and root label from qname */
+			size_t newtargetlen = qinfo->qname_len + ctargetlen - 3;
+
+			log_assert(ctargetlen >= 3);
+			log_assert(qinfo->qname_len >= 1);
+
+			if(newtargetlen > LDNS_MAX_DOMAINLEN) {
+				qinfo->local_alias = NULL;
+				local_error_encode(qinfo, env, edns, repinfo,
+					buf, temp, LDNS_RCODE_YXDOMAIN,
+					(LDNS_RCODE_YXDOMAIN|BIT_AA));
+				return 1;
+			}
+			memset(&qinfo->local_alias->rrset->entry, 0,
+				sizeof(qinfo->local_alias->rrset->entry));
+			qinfo->local_alias->rrset->entry.key =
+				qinfo->local_alias->rrset;
+			qinfo->local_alias->rrset->entry.hash =
+				rrset_key_hash(&qinfo->local_alias->rrset->rk);
+			d = (struct packed_rrset_data*)regional_alloc_zero(temp,
+				sizeof(struct packed_rrset_data) + sizeof(size_t) +
+				sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t)
+				+ newtargetlen);
+			if(!d)
+				return 0; /* out of memory */
+			qinfo->local_alias->rrset->entry.data = d;
+			d->ttl = 0; /* 0 for synthesized CNAME TTL */
+			d->count = 1;
+			d->rrsig_count = 0;
+			d->trust = rrset_trust_ans_noAA;
+			d->rr_len = (size_t*)((uint8_t*)d +
+				sizeof(struct packed_rrset_data));
+			d->rr_len[0] = newtargetlen + sizeof(uint16_t);
+			packed_rrset_ptr_fixup(d);
+			d->rr_ttl[0] = d->ttl;
+			sldns_write_uint16(d->rr_data[0], newtargetlen);
+			/* write qname */
+			memmove(d->rr_data[0] + sizeof(uint16_t), qinfo->qname,
+				qinfo->qname_len - 1);
+			/* write cname target wilcard wildcard label */
+			memmove(d->rr_data[0] + sizeof(uint16_t) +
+				qinfo->qname_len - 1, ctarget + 2,
+				ctargetlen - 2);
+		}
 		return 1;
 	}
-	if(lz_type == local_zone_redirect) {
+	if(lz_type == local_zone_redirect ||
+		lz_type == local_zone_inform_redirect) {
 		/* convert rrset name to query name; like a wildcard */
 		struct ub_packed_rrset_key r = *lr->rrset;
 		r.rk.dname = qinfo->qname;
@@ -1411,26 +1514,15 @@
 	return (lr == NULL);
 }
 
-/** 
- * Answer in case where no exact match is found.
- * @param z: zone for query.
- * @param env: module environment.
- * @param qinfo: query.
- * @param edns: edns from query.
- * @param repinfo: source address for checks. may be NULL.
- * @param buf: buffer for answer.
- * @param temp: temp region for encoding.
- * @param ld: local data, if NULL, no such name exists in localdata.
- * @param lz_type: type of the local zone.
- * @return 1 if a reply is to be sent, 0 if not.
- */
-static int
-lz_zone_answer(struct local_zone* z, struct module_env* env,
+int
+local_zones_zone_answer(struct local_zone* z, struct module_env* env,
 	struct query_info* qinfo, struct edns_data* edns,
 	struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
 	struct local_data* ld, enum localzone_type lz_type)
 {
-	if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) {
+	if(lz_type == local_zone_deny ||
+		lz_type == local_zone_always_deny ||
+		lz_type == local_zone_inform_deny) {
 		/** no reply at all, signal caller by clearing buffer. */
 		sldns_buffer_clear(buf);
 		sldns_buffer_flip(buf);
@@ -1442,7 +1534,9 @@
 		return 1;
 	} else if(lz_type == local_zone_static ||
 		lz_type == local_zone_redirect ||
-		lz_type == local_zone_always_nxdomain) {
+		lz_type == local_zone_inform_redirect ||
+		lz_type == local_zone_always_nxdomain ||
+		lz_type == local_zone_always_nodata) {
 		/* for static, reply nodata or nxdomain
 		 * for redirect, reply nodata */
 		/* no additional section processing,
@@ -1450,7 +1544,9 @@
 		 * or using closest match for NSEC.
 		 * or using closest match for returning delegation downwards
 		 */
-		int rcode = (ld || lz_type == local_zone_redirect)?
+		int rcode = (ld || lz_type == local_zone_redirect ||
+			lz_type == local_zone_inform_redirect ||
+			lz_type == local_zone_always_nodata)?
 			LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
 		if(z->soa)
 			return local_encode(qinfo, env, edns, repinfo, buf, temp,
@@ -1493,7 +1589,7 @@
 	addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
 	snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,
 		(unsigned)port);
-	log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
+	log_nametypeclass(NO_VERBOSE, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
 }
 
 static enum localzone_type
@@ -1624,7 +1720,9 @@
 		}
 	}
 	if((env->cfg->log_local_actions ||
-			lzt == local_zone_inform || lzt == local_zone_inform_deny)
+			lzt == local_zone_inform ||
+			lzt == local_zone_inform_deny ||
+			lzt == local_zone_inform_redirect)
 			&& repinfo)
 		lz_inform_print(z, qinfo, repinfo);
 
@@ -1631,6 +1729,8 @@
 	if(lzt != local_zone_always_refuse
 		&& lzt != local_zone_always_transparent
 		&& lzt != local_zone_always_nxdomain
+		&& lzt != local_zone_always_nodata
+		&& lzt != local_zone_always_deny
 		&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
 			&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
 		lock_rw_unlock(&z->lock);
@@ -1638,7 +1738,7 @@
 		 * a local alias. */
 		return !qinfo->local_alias;
 	}
-	r = lz_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
+	r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
 	lock_rw_unlock(&z->lock);
 	return r && !qinfo->local_alias; /* see above */
 }
@@ -1656,10 +1756,14 @@
 		case local_zone_nodefault: return "nodefault";
 		case local_zone_inform: return "inform";
 		case local_zone_inform_deny: return "inform_deny";
+		case local_zone_inform_redirect: return "inform_redirect";
 		case local_zone_always_transparent: return "always_transparent";
 		case local_zone_always_refuse: return "always_refuse";
 		case local_zone_always_nxdomain: return "always_nxdomain";
+		case local_zone_always_nodata: return "always_nodata";
+		case local_zone_always_deny: return "always_deny";
 		case local_zone_noview: return "noview";
+		case local_zone_invalid: return "invalid";
 	}
 	return "badtyped"; 
 }
@@ -1682,6 +1786,8 @@
 		*t = local_zone_inform;
 	else if(strcmp(type, "inform_deny") == 0)
 		*t = local_zone_inform_deny;
+	else if(strcmp(type, "inform_redirect") == 0)
+		*t = local_zone_inform_redirect;
 	else if(strcmp(type, "always_transparent") == 0)
 		*t = local_zone_always_transparent;
 	else if(strcmp(type, "always_refuse") == 0)
@@ -1688,6 +1794,10 @@
 		*t = local_zone_always_refuse;
 	else if(strcmp(type, "always_nxdomain") == 0)
 		*t = local_zone_always_nxdomain;
+	else if(strcmp(type, "always_nodata") == 0)
+		*t = local_zone_always_nodata;
+	else if(strcmp(type, "always_deny") == 0)
+		*t = local_zone_always_deny;
 	else if(strcmp(type, "noview") == 0)
 		*t = local_zone_noview;
 	else if(strcmp(type, "nodefault") == 0)
@@ -1831,7 +1941,7 @@
 			return;
 		dname_remove_label(&name, &len);
 		labs--;
-		d = lz_find_node(z, name, len, labs);
+		d = local_zone_find_data(z, name, len, labs);
 	}
 }
 
@@ -1864,7 +1974,7 @@
 	z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS);
 	if(z) {
 		lock_rw_wrlock(&z->lock);
-		d = lz_find_node(z, name, len, labs);
+		d = local_zone_find_data(z, name, len, labs);
 		if(d) {
 			del_local_rrset(d, LDNS_RR_TYPE_DS);
 			del_empty_term(z, d, name, len, labs);
@@ -1885,7 +1995,7 @@
 	lock_rw_unlock(&zones->lock);
 
 	/* find the domain */
-	d = lz_find_node(z, name, len, labs);
+	d = local_zone_find_data(z, name, len, labs);
 	if(d) {
 		/* no memory recycling for zone deletions ... */
 		d->rrsets = NULL;
--- contrib/unbound/services/localzone.h.orig
+++ contrib/unbound/services/localzone.h
@@ -46,6 +46,7 @@
 #include "util/storage/dnstree.h"
 #include "util/module.h"
 #include "services/view.h"
+#include "sldns/sbuffer.h"
 struct packed_rrset_data;
 struct ub_packed_rrset_key;
 struct regional;
@@ -83,6 +84,8 @@
 	local_zone_inform,
 	/** log client address, and block (drop) */
 	local_zone_inform_deny,
+	/** log client address, and direct */
+	local_zone_inform_redirect,
 	/** resolve normally, even when there is local data */	
 	local_zone_always_transparent,
 	/** answer with error, even when there is local data */	
@@ -89,8 +92,14 @@
 	local_zone_always_refuse,
 	/** answer with nxdomain, even when there is local data */
 	local_zone_always_nxdomain,
+	/** answer with noerror/nodata, even when there is local data */
+	local_zone_always_nodata,
+	/** drop query, even when there is local data */
+	local_zone_always_deny,
 	/** answer not from the view, but global or no-answer */
-	local_zone_noview
+	local_zone_noview,
+	/** Invalid type, cannot be used to generate answer */
+	local_zone_invalid
 };
 
 /**
@@ -308,6 +317,25 @@
 	struct config_strlist** tag_datas, size_t tag_datas_size,
 	char** tagname, int num_tags, struct view* view);
 
+/** 
+ * Answer using the local zone only (not local data used).
+ * @param z: zone for query.
+ * @param env: module environment.
+ * @param qinfo: query.
+ * @param edns: edns from query.
+ * @param repinfo: source address for checks. may be NULL.
+ * @param buf: buffer for answer.
+ * @param temp: temp region for encoding.
+ * @param ld: local data, if NULL, no such name exists in localdata.
+ * @param lz_type: type of the local zone.
+ * @return 1 if a reply is to be sent, 0 if not.
+ */
+int
+local_zones_zone_answer(struct local_zone* z, struct module_env* env,
+	struct query_info* qinfo, struct edns_data* edns,
+	struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
+	struct local_data* ld, enum localzone_type lz_type);
+
 /**
  * Parse the string into localzone type.
  *
@@ -339,6 +367,22 @@
 	uint8_t* name, size_t len, int labs, uint16_t dclass);
 
 /**
+ * Find zone that with exactly or smaller name/class
+ * User must lock the tree or result zone.
+ * @param zones: the zones tree
+ * @param name: dname to lookup
+ * @param len: length of name.
+ * @param labs: labelcount of name.
+ * @param dclass: class to lookup.
+ * @param exact: 1 on return is this is an exact match.
+ * @return the exact or smaller local_zone or NULL.
+ */
+struct local_zone*
+local_zones_find_le(struct local_zones* zones,
+        uint8_t* name, size_t len, int labs, uint16_t dclass,
+	int* exact);
+
+/**
  * Add a new zone. Caller must hold the zones lock.
  * Adjusts the other zones as well (parent pointers) after insertion.
  * The zone must NOT exist (returns NULL and logs error).
@@ -472,6 +516,15 @@
 	uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
 
 /**
+ * Remove RR from rrset that is created using localzone's rrset_insert_rr.
+ * @param pd: the RRset containing the RR to remove
+ * @param index: index of RR to remove
+ * @return: 1 on success; 0 otherwise.
+ */
+int
+local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index);
+
+/**
   * Valid response ip actions for the IP-response-driven-action feature;
   * defined here instead of in the respip module to enable sharing of enum
   * values with the localzone_type enum.
@@ -491,6 +544,8 @@
 	respip_inform = local_zone_inform,
         /** log query source and don't answer query */
 	respip_inform_deny = local_zone_inform_deny,
+        /** log query source and redirect */
+	respip_inform_redirect = local_zone_inform_redirect,
         /** resolve normally, even when there is response-ip data */
 	respip_always_transparent = local_zone_always_transparent,
         /** answer with 'refused' response */
@@ -497,6 +552,10 @@
 	respip_always_refuse = local_zone_always_refuse,
         /** answer with 'no such domain' response */
 	respip_always_nxdomain = local_zone_always_nxdomain,
+        /** answer with nodata response */
+	respip_always_nodata = local_zone_always_nodata,
+        /** answer with nodata response */
+	respip_always_deny = local_zone_always_deny,
 
 	/* The rest of the values are only possible as
 	 * access-control-tag-action */
@@ -509,6 +568,64 @@
 	respip_transparent = local_zone_transparent,
 	/** gives response data (if any), else nodata answer. */
 	respip_typetransparent = local_zone_typetransparent,
+	/** type invalid */
+	respip_invalid = local_zone_invalid,
 };
 
+/**
+ * Get local data from local zone and encode answer.
+ * @param z: local zone to use
+ * @param env: module env
+ * @param qinfo: qinfo
+ * @param edns: edns data, for message encoding
+ * @param repinfo: reply info, for message encoding
+ * @param buf: commpoint buffer
+ * @param temp: scratchpad region
+ * @param labs: number of labels in qname
+ * @param ldp: where to store local data
+ * @param lz_type: type of local zone
+ * @param tag: matching tag index
+ * @param tag_datas: alc specific tag data list
+ * @param tag_datas_size: size of tag_datas
+ * @param tagname: list of names of tags, for logging purpose
+ * @param num_tags: number of tags
+ * @return 1 on success
+ */
+int
+local_data_answer(struct local_zone* z, struct module_env* env,
+	struct query_info* qinfo, struct edns_data* edns,
+	struct comm_reply* repinfo, sldns_buffer* buf,
+	struct regional* temp, int labs, struct local_data** ldp,
+	enum localzone_type lz_type, int tag, struct config_strlist** tag_datas,
+	size_t tag_datas_size, char** tagname, int num_tags);
+
+/**
+ * Add RR to local zone.
+ * @param z: local zone to add RR to
+ * @param nm: dname of RR
+ * @param nmlen: length of nm
+ * @param nmlabs: number of labels of nm
+ * @param rrtype: RR type
+ * @param rrclass: RR class
+ * @param ttl: TTL of RR to add
+ * @param rdata: RDATA of RR to add
+ * @param rdata_len: length of rdata
+ * @param rrstr: RR in string format, for logging
+ * @return: 1 on success
+ */
+int
+local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
+	int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
+	uint8_t* rdata, size_t rdata_len, const char* rrstr);
+
+/**
+ * Find a data node by exact name for a local zone
+ * @param z: local_zone containing data tree
+ * @param nm: name of local-data element to find
+ * @param nmlen: length of nm
+ * @param nmlabs: labs of nm
+ * @return local_data on exact match, NULL otherwise.
+ */
+struct local_data* 
+local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
 #endif /* SERVICES_LOCALZONE_H */
--- contrib/unbound/services/mesh.c.orig
+++ contrib/unbound/services/mesh.c
@@ -46,6 +46,7 @@
 #include "services/mesh.h"
 #include "services/outbound_list.h"
 #include "services/cache/dns.h"
+#include "services/cache/rrset.h"
 #include "util/log.h"
 #include "util/net_help.h"
 #include "util/module.h"
@@ -61,6 +62,7 @@
 #include "services/localzone.h"
 #include "util/data/dname.h"
 #include "respip/respip.h"
+#include "services/listen_dnsport.h"
 
 /** subtract timers and the values do not overflow or become negative */
 static void
@@ -84,7 +86,7 @@
 #ifndef S_SPLINT_S
 	d->tv_sec += add->tv_sec;
 	d->tv_usec += add->tv_usec;
-	if(d->tv_usec > 1000000 ) {
+	if(d->tv_usec >= 1000000 ) {
 		d->tv_usec -= 1000000;
 		d->tv_sec++;
 	}
@@ -126,7 +128,7 @@
 #endif
 }
 
-/*
+/**
  * Compare two response-ip client info entries for the purpose of mesh state
  * compare.  It returns 0 if ci_a and ci_b are considered equal; otherwise
  * 1 or -1 (they mean 'ci_a is larger/smaller than ci_b', respectively, but
@@ -249,6 +251,7 @@
 	mesh->num_forever_states = 0;
 	mesh->stats_jostled = 0;
 	mesh->stats_dropped = 0;
+	mesh->ans_expired = 0;
 	mesh->max_reply_states = env->cfg->num_queries_per_thread;
 	mesh->max_forever_states = (mesh->max_reply_states+1)/2;
 #ifndef S_SPLINT_S
@@ -344,6 +347,97 @@
 	return 0;
 }
 
+struct dns_msg*
+mesh_serve_expired_lookup(struct module_qstate* qstate,
+	struct query_info* lookup_qinfo)
+{
+	hashvalue_type h;
+	struct lruhash_entry* e;
+	struct dns_msg* msg;
+	struct reply_info* data;
+	struct msgreply_entry* key;
+	time_t timenow = *qstate->env->now;
+	int must_validate = (!(qstate->query_flags&BIT_CD)
+		|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
+	/* Lookup cache */
+	h = query_info_hash(lookup_qinfo, qstate->query_flags);
+	e = slabhash_lookup(qstate->env->msg_cache, h, lookup_qinfo, 0);
+	if(!e) return NULL;
+
+	key = (struct msgreply_entry*)e->key;
+	data = (struct reply_info*)e->data;
+	msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow,
+		qstate->env->cfg->serve_expired, qstate->env->scratch);
+	if(!msg)
+		goto bail_out;
+
+	/* Check CNAME chain (if any)
+	 * This is part of tomsg above; no need to check now. */
+
+	/* Check security status of the cached answer.
+	 * tomsg above has a subset of these checks, so we are leaving
+	 * these as is.
+	 * In case of bogus or revalidation we don't care to reply here. */
+	if(must_validate && (msg->rep->security == sec_status_bogus ||
+		msg->rep->security == sec_status_secure_sentinel_fail)) {
+		verbose(VERB_ALGO, "Serve expired: bogus answer found in cache");
+		goto bail_out;
+	} else if(msg->rep->security == sec_status_unchecked && must_validate) {
+		verbose(VERB_ALGO, "Serve expired: unchecked entry needs "
+			"validation");
+		goto bail_out; /* need to validate cache entry first */
+	} else if(msg->rep->security == sec_status_secure &&
+		!reply_all_rrsets_secure(msg->rep) && must_validate) {
+			verbose(VERB_ALGO, "Serve expired: secure entry"
+				" changed status");
+			goto bail_out; /* rrset changed, re-verify */
+	}
+
+	lock_rw_unlock(&e->lock);
+	return msg;
+
+bail_out:
+	lock_rw_unlock(&e->lock);
+	return NULL;
+}
+
+
+/** Init the serve expired data structure */
+static int
+mesh_serve_expired_init(struct mesh_state* mstate, int timeout)
+{
+	struct timeval t;
+
+	/* Create serve_expired_data if not there yet */
+	if(!mstate->s.serve_expired_data) {
+		mstate->s.serve_expired_data = (struct serve_expired_data*)
+			regional_alloc_zero(
+				mstate->s.region, sizeof(struct serve_expired_data));
+		if(!mstate->s.serve_expired_data)
+			return 0;
+	}
+
+	/* Don't overwrite the function if already set */
+	mstate->s.serve_expired_data->get_cached_answer =
+		mstate->s.serve_expired_data->get_cached_answer?
+		mstate->s.serve_expired_data->get_cached_answer:
+		mesh_serve_expired_lookup;
+
+	/* In case this timer already popped, start it again */
+	if(!mstate->s.serve_expired_data->timer) {
+		mstate->s.serve_expired_data->timer = comm_timer_create(
+			mstate->s.env->worker_base, mesh_serve_expired_callback, mstate);
+		if(!mstate->s.serve_expired_data->timer)
+			return 0;
+#ifndef S_SPLINT_S
+		t.tv_sec = timeout/1000;
+		t.tv_usec = (timeout%1000)*1000;
+#endif
+		comm_timer_set(mstate->s.serve_expired_data->timer, &t);
+	}
+	return 1;
+}
+
 void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
 	struct respip_client_info* cinfo, uint16_t qflags,
 	struct edns_data* edns, struct comm_reply* rep, uint16_t qid)
@@ -353,6 +447,12 @@
 	int was_detached = 0;
 	int was_noreply = 0;
 	int added = 0;
+	int timeout = mesh->env->cfg->serve_expired?
+		mesh->env->cfg->serve_expired_client_timeout:0;
+	struct sldns_buffer* r_buffer = rep->c->buffer;
+	if(rep->c->tcp_req_info) {
+		r_buffer = rep->c->tcp_req_info->spool_buffer;
+	}
 	if(!unique)
 		s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
 	/* does this create a new reply state? */
@@ -361,7 +461,7 @@
 			verbose(VERB_ALGO, "Too many queries. dropping "
 				"incoming query.");
 			comm_point_drop_reply(rep);
-			mesh->stats_dropped ++;
+			mesh->stats_dropped++;
 			return;
 		}
 		/* for this new reply state, the reply address is free,
@@ -371,8 +471,8 @@
 		if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
 			verbose(VERB_ALGO, "Too many requests queued. "
 				"dropping incoming query.");
+			comm_point_drop_reply(rep);
 			mesh->stats_dropped++;
-			comm_point_drop_reply(rep);
 			return;
 		}
 	}
@@ -388,7 +488,7 @@
 			if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
 				LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
 					edns->opt_list = NULL;
-			error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
+			error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
 				qinfo, qid, qflags, edns);
 			comm_point_send_reply(rep);
 			return;
@@ -404,7 +504,7 @@
 				if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
 					NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
 						edns->opt_list = NULL;
-				error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
+				error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
 					qinfo, qid, qflags, edns);
 				comm_point_send_reply(rep);
 				return;
@@ -422,23 +522,28 @@
 		mesh->num_detached_states++;
 		added = 1;
 	}
-	if(!s->reply_list && !s->cb_list && s->super_set.count == 0)
-		was_detached = 1;
-	if(!s->reply_list && !s->cb_list)
+	if(!s->reply_list && !s->cb_list) {
 		was_noreply = 1;
+		if(s->super_set.count == 0) {
+			was_detached = 1;
+		}
+	}
 	/* add reply to s */
 	if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) {
-			log_err("mesh_new_client: out of memory; SERVFAIL");
-			if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
-				NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
-					edns->opt_list = NULL;
-			error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
-				qinfo, qid, qflags, edns);
-			comm_point_send_reply(rep);
-			if(added)
-				mesh_state_delete(&s->s);
-			return;
+		log_err("mesh_new_client: out of memory; SERVFAIL");
+		goto servfail_mem;
 	}
+	if(rep->c->tcp_req_info) {
+		if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) {
+			log_err("mesh_new_client: out of memory add tcpreqinfo");
+			goto servfail_mem;
+		}
+	}
+	/* add serve expired timer if required and not already there */
+	if(timeout && !mesh_serve_expired_init(s, timeout)) {
+		log_err("mesh_new_client: out of memory initializing serve expired");
+		goto servfail_mem;
+	}
 	/* update statistics */
 	if(was_detached) {
 		log_assert(mesh->num_detached_states > 0);
@@ -463,6 +568,18 @@
 	}
 	if(added)
 		mesh_run(mesh, s, module_event_new, NULL);
+	return;
+
+servfail_mem:
+	if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
+		NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
+			edns->opt_list = NULL;
+	error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
+		qinfo, qid, qflags, edns);
+	comm_point_send_reply(rep);
+	if(added)
+		mesh_state_delete(&s->s);
+	return;
 }
 
 int 
@@ -472,6 +589,8 @@
 {
 	struct mesh_state* s = NULL;
 	int unique = unique_mesh_state(edns->opt_list, mesh->env);
+	int timeout = mesh->env->cfg->serve_expired?
+		mesh->env->cfg->serve_expired_client_timeout:0;
 	int was_detached = 0;
 	int was_noreply = 0;
 	int added = 0;
@@ -510,16 +629,22 @@
 		mesh->num_detached_states++;
 		added = 1;
 	}
-	if(!s->reply_list && !s->cb_list && s->super_set.count == 0)
-		was_detached = 1;
-	if(!s->reply_list && !s->cb_list)
+	if(!s->reply_list && !s->cb_list) {
 		was_noreply = 1;
+		if(s->super_set.count == 0) {
+			was_detached = 1;
+		}
+	}
 	/* add reply to s */
 	if(!mesh_state_add_cb(s, edns, buf, cb, cb_arg, qid, qflags)) {
-			if(added)
-				mesh_state_delete(&s->s);
-			return 0;
+		if(added)
+			mesh_state_delete(&s->s);
+		return 0;
 	}
+	/* add serve expired timer if not already there */
+	if(timeout && !mesh_serve_expired_init(s, timeout)) {
+		return 0;
+	}
 	/* update statistics */
 	if(was_detached) {
 		log_assert(mesh->num_detached_states > 0);
@@ -534,15 +659,6 @@
 	return 1;
 }
 
-static void mesh_schedule_prefetch(struct mesh_area* mesh,
-	struct query_info* qinfo, uint16_t qflags, time_t leeway, int run);
-
-void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
-        uint16_t qflags, time_t leeway)
-{
-	mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1);
-}
-
 /* Internal backend routine of mesh_new_prefetch().  It takes one additional
  * parameter, 'run', which controls whether to run the prefetch state
  * immediately.  When this function is called internally 'run' could be
@@ -619,6 +735,12 @@
 	mesh_run(mesh, s, module_event_new, NULL);
 }
 
+void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
+        uint16_t qflags, time_t leeway)
+{
+	mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1);
+}
+
 void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
         struct comm_reply* reply, int what)
 {
@@ -691,6 +813,7 @@
 	mstate->s.env = env;
 	mstate->s.mesh_info = mstate;
 	mstate->s.prefetch_leeway = 0;
+	mstate->s.serve_expired_data = NULL;
 	mstate->s.no_cache_lookup = 0;
 	mstate->s.no_cache_store = 0;
 	mstate->s.need_refetch = 0;
@@ -730,12 +853,22 @@
 	if(!mstate)
 		return;
 	mesh = mstate->s.env->mesh;
+	/* Stop and delete the serve expired timer */
+	if(mstate->s.serve_expired_data && mstate->s.serve_expired_data->timer) {
+		comm_timer_delete(mstate->s.serve_expired_data->timer);
+		mstate->s.serve_expired_data->timer = NULL;
+	}
 	/* drop unsent replies */
 	if(!mstate->replies_sent) {
-		struct mesh_reply* rep;
+		struct mesh_reply* rep = mstate->reply_list;
 		struct mesh_cb* cb;
-		for(rep=mstate->reply_list; rep; rep=rep->next) {
+		/* in tcp_req_info, the mstates linked are removed, but
+		 * the reply_list is now NULL, so the remove-from-empty-list
+		 * takes no time and also it does not do the mesh accounting */
+		mstate->reply_list = NULL;
+		for(; rep; rep=rep->next) {
 			comm_point_drop_reply(&rep->query_reply);
+			log_assert(mesh->num_reply_addrs > 0);
 			mesh->num_reply_addrs--;
 		}
 		while((cb = mstate->cb_list)!=NULL) {
@@ -743,6 +876,7 @@
 			fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
 			(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
 				sec_status_unchecked, NULL, 0);
+			log_assert(mesh->num_reply_addrs > 0);
 			mesh->num_reply_addrs--;
 		}
 	}
@@ -810,7 +944,7 @@
 }
 
 /** find cycle for already looked up mesh_state */
-static int 
+static int
 mesh_detect_cycle_found(struct module_qstate* qstate, struct mesh_state* dep_m)
 {
 	struct mesh_state* cyc_m = qstate->mesh_info;
@@ -1022,6 +1156,7 @@
 		}
 	}
 	free(reason);
+	log_assert(m->s.env->mesh->num_reply_addrs > 0);
 	m->s.env->mesh->num_reply_addrs--;
 }
 
@@ -1031,11 +1166,14 @@
  * @param rcode: if not 0, error code.
  * @param rep: reply to send (or NULL if rcode is set).
  * @param r: reply entry
+ * @param r_buffer: buffer to use for reply entry.
  * @param prev: previous reply, already has its answer encoded in buffer.
+ * @param prev_buffer: buffer for previous reply.
  */
 static void
 mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
-	struct mesh_reply* r, struct mesh_reply* prev)
+	struct mesh_reply* r, struct sldns_buffer* r_buffer,
+	struct mesh_reply* prev, struct sldns_buffer* prev_buffer)
 {
 	struct timeval end_time;
 	struct timeval duration;
@@ -1063,7 +1201,7 @@
 	 * and still reuse the previous answer if they are the same, but that
 	 * would be complicated and error prone for the relatively minor case.
 	 * So we err on the side of safety. */
-	if(prev && prev->qflags == r->qflags && 
+	if(prev && prev_buffer && prev->qflags == r->qflags && 
 		!prev->local_alias && !r->local_alias &&
 		prev->edns.edns_present == r->edns.edns_present && 
 		prev->edns.bits == r->edns.bits && 
@@ -1071,13 +1209,11 @@
 		edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list)
 		== 0) {
 		/* if the previous reply is identical to this one, fix ID */
-		if(prev->query_reply.c->buffer != r->query_reply.c->buffer)
-			sldns_buffer_copy(r->query_reply.c->buffer, 
-				prev->query_reply.c->buffer);
-		sldns_buffer_write_at(r->query_reply.c->buffer, 0, 
-			&r->qid, sizeof(uint16_t));
-		sldns_buffer_write_at(r->query_reply.c->buffer, 12, 
-			r->qname, m->s.qinfo.qname_len);
+		if(prev_buffer != r_buffer)
+			sldns_buffer_copy(r_buffer, prev_buffer);
+		sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t));
+		sldns_buffer_write_at(r_buffer, 12, r->qname,
+			m->s.qinfo.qname_len);
 		comm_point_send_reply(&r->query_reply);
 	} else if(rcode) {
 		m->s.qinfo.qname = r->qname;
@@ -1091,8 +1227,8 @@
 				&r->edns, NULL, m->s.region))
 					r->edns.opt_list = NULL;
 		}
-		error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
-			r->qid, r->qflags, &r->edns);
+		error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
+			r->qflags, &r->edns);
 		comm_point_send_reply(&r->query_reply);
 	} else {
 		size_t udp_size = r->edns.udp_size;
@@ -1108,21 +1244,21 @@
 				m->s.env->cfg, r->query_reply.c,
 				m->s.region) ||
 			!reply_info_answer_encode(&m->s.qinfo, rep, r->qid, 
-			r->qflags, r->query_reply.c->buffer, 0, 1, 
-			m->s.env->scratch, udp_size, &r->edns, 
-			(int)(r->edns.bits & EDNS_DO), secure)) 
+			r->qflags, r_buffer, 0, 1, m->s.env->scratch,
+			udp_size, &r->edns, (int)(r->edns.bits & EDNS_DO),
+			secure)) 
 		{
 			if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
 			rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region))
 				r->edns.opt_list = NULL;
-			error_encode(r->query_reply.c->buffer, 
-				LDNS_RCODE_SERVFAIL, &m->s.qinfo, r->qid, 
-				r->qflags, &r->edns);
+			error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
+				&m->s.qinfo, r->qid, r->qflags, &r->edns);
 		}
 		r->edns = edns_bak;
 		comm_point_send_reply(&r->query_reply);
 	}
 	/* account */
+	log_assert(m->s.env->mesh->num_reply_addrs > 0);
 	m->s.env->mesh->num_reply_addrs--;
 	end_time = *m->s.env->now_tv;
 	timeval_subtract(&duration, &end_time, &r->start_time);
@@ -1132,57 +1268,105 @@
 	timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
 	timehist_insert(m->s.env->mesh->histogram, &duration);
 	if(m->s.env->cfg->stat_extended) {
-		uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(r->
-			query_reply.c->buffer, 2));
+		uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(
+			r_buffer, 2));
 		if(secure) m->s.env->mesh->ans_secure++;
 		m->s.env->mesh->ans_rcode[ rc ] ++;
-		if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r->
-			query_reply.c->buffer)) == 0)
+		if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r_buffer)) == 0)
 			m->s.env->mesh->ans_nodata++;
 	}
 	/* Log reply sent */
 	if(m->s.env->cfg->log_replies) {
-		log_reply_info(0, &m->s.qinfo, &r->query_reply.addr,
-			r->query_reply.addrlen, duration, 0,
-			r->query_reply.c->buffer);
+		log_reply_info(NO_VERBOSE, &m->s.qinfo, &r->query_reply.addr,
+			r->query_reply.addrlen, duration, 0, r_buffer);
 	}
 }
 
 void mesh_query_done(struct mesh_state* mstate)
 {
-	struct mesh_reply* r;
+	struct mesh_reply* r, *reply_list = NULL;
 	struct mesh_reply* prev = NULL;
+	struct sldns_buffer* prev_buffer = NULL;
 	struct mesh_cb* c;
 	struct reply_info* rep = (mstate->s.return_msg?
 		mstate->s.return_msg->rep:NULL);
-	if((mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||
-		(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL))
+	/* No need for the serve expired timer anymore; we are going to reply. */
+	if(mstate->s.serve_expired_data) {
+		comm_timer_delete(mstate->s.serve_expired_data->timer);
+		mstate->s.serve_expired_data->timer = NULL;
+	}
+	if(mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||
+		(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL)) {
+		/* we are SERVFAILing; check for expired asnwer here */
+		mesh_serve_expired_callback(mstate);
+		if((mstate->reply_list || mstate->cb_list)
 		&& mstate->s.env->cfg->log_servfail
 		&& !mstate->s.env->cfg->val_log_squelch) {
-		char* err = errinf_to_str_servfail(&mstate->s);
-		if(err)
-			log_err("%s", err);
-		free(err);
+			char* err = errinf_to_str_servfail(&mstate->s);
+			if(err)
+				log_err("%s", err);
+			free(err);
+		}
 	}
-	for(r = mstate->reply_list; r; r = r->next) {
+	if(mstate->reply_list) {
+		/* set the reply_list to NULL during the mesh_query_done
+		 * processing, so that calls back into the mesh from
+		 * tcp_req_info (deciding to drop the reply and thus
+		 * unregister the mesh_reply from the mstate) are stopped
+		 * because the list is empty.
+		 * The mstate is then likely not a reply_state, and maybe
+		 * also a detached_state.
+		 */
+		reply_list = mstate->reply_list;
+		mstate->reply_list = NULL;
+		if(!mstate->reply_list && !mstate->cb_list) {
+			/* was a reply state, not anymore */
+			log_assert(mstate->s.env->mesh->num_reply_states > 0);
+			mstate->s.env->mesh->num_reply_states--;
+		}
+		if(!mstate->reply_list && !mstate->cb_list &&
+			mstate->super_set.count == 0)
+			mstate->s.env->mesh->num_detached_states++;
+	}
+	for(r = reply_list; r; r = r->next) {
 		/* if a response-ip address block has been stored the
 		 *  information should be logged for each client. */
 		if(mstate->s.respip_action_info &&
 			mstate->s.respip_action_info->addrinfo) {
-			respip_inform_print(mstate->s.respip_action_info->addrinfo,
+			respip_inform_print(mstate->s.respip_action_info,
 				r->qname, mstate->s.qinfo.qtype,
 				mstate->s.qinfo.qclass, r->local_alias,
 				&r->query_reply);
+			if(mstate->s.env->cfg->stat_extended &&
+				mstate->s.respip_action_info->rpz_used) {
+				if(mstate->s.respip_action_info->rpz_disabled)
+					mstate->s.env->mesh->rpz_action[RPZ_DISABLED_ACTION]++;
+				if(mstate->s.respip_action_info->rpz_cname_override)
+					mstate->s.env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
+				else
+					mstate->s.env->mesh->rpz_action[respip_action_to_rpz_action(
+						mstate->s.respip_action_info->action)]++;
+			}
 		}
 
 		/* if this query is determined to be dropped during the
 		 * mesh processing, this is the point to take that action. */
-		if(mstate->s.is_drop)
+		if(mstate->s.is_drop) {
 			comm_point_drop_reply(&r->query_reply);
-		else {
+		} else {
+			struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
+			if(r->query_reply.c->tcp_req_info) {
+				r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
+				prev_buffer = NULL;
+			}
 			mesh_send_reply(mstate, mstate->s.return_rcode, rep,
-				r, prev);
+				r, r_buffer, prev, prev_buffer);
+			if(r->query_reply.c->tcp_req_info) {
+				tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
+				r_buffer = NULL;
+			}
 			prev = r;
+			prev_buffer = r_buffer;
 		}
 	}
 	mstate->replies_sent = 1;
@@ -1191,6 +1375,7 @@
 		 * changed, eg. by adds from the callback routine */
 		if(!mstate->reply_list && mstate->cb_list && !c->next) {
 			/* was a reply state, not anymore */
+			log_assert(mstate->s.env->mesh->num_reply_states > 0);
 			mstate->s.env->mesh->num_reply_states--;
 		}
 		mstate->cb_list = c->next;
@@ -1315,30 +1500,24 @@
 		log_assert(!qinfo->local_alias->next && dsrc->count == 1 &&
 			qinfo->local_alias->rrset->rk.type ==
 			htons(LDNS_RR_TYPE_CNAME));
-		/* Technically, we should make a local copy for the owner
-		 * name of the RRset, but in the case of the first (and
-		 * currently only) local alias RRset, the owner name should
-		 * point to the qname of the corresponding query, which should
-		 * be valid throughout the lifetime of this mesh_reply.  So
-		 * we can skip copying. */
-		log_assert(qinfo->local_alias->rrset->rk.dname ==
-			sldns_buffer_at(rep->c->buffer, LDNS_HEADER_SIZE));
+		/* we should make a local copy for the owner name of
+		 * the RRset */
+		r->local_alias->rrset->rk.dname_len =
+			qinfo->local_alias->rrset->rk.dname_len;
+		r->local_alias->rrset->rk.dname = regional_alloc_init(
+			s->s.region, qinfo->local_alias->rrset->rk.dname,
+			qinfo->local_alias->rrset->rk.dname_len);
+		if(!r->local_alias->rrset->rk.dname)
+			return 0;
 
-		d = regional_alloc_init(s->s.region, dsrc,
-			sizeof(struct packed_rrset_data)
-			+ sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t));
+		/* the rrset is not packed, like in the cache, but it is
+		 * individualy allocated with an allocator from localzone. */
+		d = regional_alloc_zero(s->s.region, sizeof(*d));
 		if(!d)
 			return 0;
 		r->local_alias->rrset->entry.data = d;
-		d->rr_len = (size_t*)((uint8_t*)d +
-			sizeof(struct packed_rrset_data));
-		d->rr_data = (uint8_t**)&(d->rr_len[1]);
-		d->rr_ttl = (time_t*)&(d->rr_data[1]);
-		d->rr_len[0] = dsrc->rr_len[0];
-		d->rr_ttl[0] = dsrc->rr_ttl[0];
-		d->rr_data[0] = regional_alloc_init(s->s.region,
-			dsrc->rr_data[0], d->rr_len[0]);
-		if(!d->rr_data[0])
+		if(!rrset_insert_rr(s->s.region, d, dsrc->rr_data[0],
+			dsrc->rr_len[0], dsrc->rr_ttl[0], "CNAME local alias"))
 			return 0;
 	} else
 		r->local_alias = NULL;
@@ -1392,7 +1571,7 @@
 		/* module is looping. Stop it. */
 		log_err("internal error: looping module (%s) stopped",
 			mesh->mods.mod[mstate->s.curmod]->name);
-		log_query_info(VERB_QUERY, "pass error for qstate",
+		log_query_info(NO_VERBOSE, "pass error for qstate",
 			&mstate->s.qinfo);
 		s = module_error;
 	}
@@ -1562,7 +1741,9 @@
 	timehist_clear(mesh->histogram);
 	mesh->ans_secure = 0;
 	mesh->ans_bogus = 0;
-	memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*16);
+	mesh->ans_expired = 0;
+	memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
+	memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
 	mesh->ans_nodata = 0;
 }
 
@@ -1613,3 +1794,212 @@
 		m->prev->next = m->next;
 	else	*fp = m->next;
 }
+
+void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
+	struct comm_point* cp)
+{
+	struct mesh_reply* n, *prev = NULL;
+	n = m->reply_list;
+	/* when in mesh_cleanup, it sets the reply_list to NULL, so that
+	 * there is no accounting twice */
+	if(!n) return; /* nothing to remove, also no accounting needed */
+	while(n) {
+		if(n->query_reply.c == cp) {
+			/* unlink it */
+			if(prev) prev->next = n->next;
+			else m->reply_list = n->next;
+			/* delete it, but allocated in m region */
+			log_assert(mesh->num_reply_addrs > 0);
+			mesh->num_reply_addrs--;
+
+			/* prev = prev; */
+			n = n->next;
+			continue;
+		}
+		prev = n;
+		n = n->next;
+	}
+	/* it was not detached (because it had a reply list), could be now */
+	if(!m->reply_list && !m->cb_list
+		&& m->super_set.count == 0) {
+		mesh->num_detached_states++;
+	}
+	/* if not replies any more in mstate, it is no longer a reply_state */
+	if(!m->reply_list && !m->cb_list) {
+		log_assert(mesh->num_reply_states > 0);
+		mesh->num_reply_states--;
+	}
+}
+
+
+static int
+apply_respip_action(struct module_qstate* qstate,
+	const struct query_info* qinfo, struct respip_client_info* cinfo,
+	struct respip_action_info* actinfo, struct reply_info* rep,
+	struct ub_packed_rrset_key** alias_rrset,
+	struct reply_info** encode_repp, struct auth_zones* az)
+{
+	if(qinfo->qtype != LDNS_RR_TYPE_A &&
+		qinfo->qtype != LDNS_RR_TYPE_AAAA &&
+		qinfo->qtype != LDNS_RR_TYPE_ANY)
+		return 1;
+
+	if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, actinfo,
+		alias_rrset, 0, qstate->region, az))
+		return 0;
+
+	/* xxx_deny actions mean dropping the reply, unless the original reply
+	 * was redirected to response-ip data. */
+	if((actinfo->action == respip_deny ||
+		actinfo->action == respip_inform_deny) &&
+		*encode_repp == rep)
+		*encode_repp = NULL;
+
+	return 1;
+}
+
+void
+mesh_serve_expired_callback(void* arg)
+{
+	struct mesh_state* mstate = (struct mesh_state*) arg;
+	struct module_qstate* qstate = &mstate->s;
+	struct mesh_reply* r;
+	struct mesh_area* mesh = qstate->env->mesh;
+	struct dns_msg* msg;
+	struct mesh_cb* c;
+	struct mesh_reply* prev = NULL;
+	struct sldns_buffer* prev_buffer = NULL;
+	struct sldns_buffer* r_buffer = NULL;
+	struct reply_info* partial_rep = NULL;
+	struct ub_packed_rrset_key* alias_rrset = NULL;
+	struct reply_info* encode_rep = NULL;
+	struct respip_action_info actinfo;
+	struct query_info* lookup_qinfo = &qstate->qinfo;
+	struct query_info qinfo_tmp;
+	int must_validate = (!(qstate->query_flags&BIT_CD)
+		|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
+	if(!qstate->serve_expired_data) return;
+	verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data");
+	comm_timer_delete(qstate->serve_expired_data->timer);
+	qstate->serve_expired_data->timer = NULL;
+	if(qstate->blacklist || qstate->no_cache_lookup || qstate->is_drop) {
+		verbose(VERB_ALGO,
+			"Serve expired: Not allowed to look into cache for stale");
+		return;
+	}
+	/* The following while is used instead of the `goto lookup_cache`
+	 * like in the worker. */
+	while(1) {
+		fptr_ok(fptr_whitelist_serve_expired_lookup(
+			qstate->serve_expired_data->get_cached_answer));
+		msg = qstate->serve_expired_data->get_cached_answer(qstate,
+			lookup_qinfo);
+		if(!msg)
+			return;
+		/* Reset these in case we pass a second time from here. */
+		encode_rep = msg->rep;
+		memset(&actinfo, 0, sizeof(actinfo));
+		actinfo.action = respip_none;
+		alias_rrset = NULL;
+		if((mesh->use_response_ip || mesh->use_rpz) &&
+			!partial_rep && !apply_respip_action(qstate, &qstate->qinfo,
+			qstate->client_info, &actinfo, msg->rep, &alias_rrset, &encode_rep,
+			qstate->env->auth_zones)) {
+			return;
+		} else if(partial_rep &&
+			!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
+			qstate->client_info, must_validate, &encode_rep, qstate->region,
+			qstate->env->auth_zones)) {
+			return;
+		}
+		if(!encode_rep || alias_rrset) {
+			if(!encode_rep) {
+				/* Needs drop */
+				return;
+			} else {
+				/* A partial CNAME chain is found. */
+				partial_rep = encode_rep;
+			}
+		}
+		/* We've found a partial reply ending with an
+		* alias.  Replace the lookup qinfo for the
+		* alias target and lookup the cache again to
+		* (possibly) complete the reply.  As we're
+		* passing the "base" reply, there will be no
+		* more alias chasing. */
+		if(partial_rep) {
+			memset(&qinfo_tmp, 0, sizeof(qinfo_tmp));
+			get_cname_target(alias_rrset, &qinfo_tmp.qname,
+				&qinfo_tmp.qname_len);
+			if(!qinfo_tmp.qname) {
+				log_err("Serve expired: unexpected: invalid answer alias");
+				return;
+			}
+			qinfo_tmp.qtype = qstate->qinfo.qtype;
+			qinfo_tmp.qclass = qstate->qinfo.qclass;
+			lookup_qinfo = &qinfo_tmp;
+			continue;
+		}
+		break;
+	}
+
+	if(verbosity >= VERB_ALGO)
+		log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
+
+	r = mstate->reply_list;
+	mstate->reply_list = NULL;
+	if(!mstate->reply_list && !mstate->cb_list) {
+		log_assert(mesh->num_reply_states > 0);
+		mesh->num_reply_states--;
+		if(mstate->super_set.count == 0) {
+			mesh->num_detached_states++;
+		}
+	}
+	for(; r; r = r->next) {
+		/* If address info is returned, it means the action should be an
+		* 'inform' variant and the information should be logged. */
+		if(actinfo.addrinfo) {
+			respip_inform_print(&actinfo, r->qname,
+				qstate->qinfo.qtype, qstate->qinfo.qclass,
+				r->local_alias, &r->query_reply);
+
+			if(qstate->env->cfg->stat_extended && actinfo.rpz_used) {
+				if(actinfo.rpz_disabled)
+					qstate->env->mesh->rpz_action[RPZ_DISABLED_ACTION]++;
+				if(actinfo.rpz_cname_override)
+					qstate->env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
+				else
+					qstate->env->mesh->rpz_action[
+						respip_action_to_rpz_action(actinfo.action)]++;
+			}
+		}
+
+		r_buffer = r->query_reply.c->buffer;
+		if(r->query_reply.c->tcp_req_info)
+			r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
+		mesh_send_reply(mstate, LDNS_RCODE_NOERROR, msg->rep,
+			r, r_buffer, prev, prev_buffer);
+		if(r->query_reply.c->tcp_req_info)
+			tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
+		prev = r;
+		prev_buffer = r_buffer;
+
+		/* Account for each reply sent. */
+		mesh->ans_expired++;
+
+	}
+	while((c = mstate->cb_list) != NULL) {
+		/* take this cb off the list; so that the list can be
+		 * changed, eg. by adds from the callback routine */
+		if(!mstate->reply_list && mstate->cb_list && !c->next) {
+			/* was a reply state, not anymore */
+			log_assert(qstate->env->mesh->num_reply_states > 0);
+			qstate->env->mesh->num_reply_states--;
+		}
+		mstate->cb_list = c->next;
+		if(!mstate->reply_list && !mstate->cb_list &&
+			mstate->super_set.count == 0)
+			qstate->env->mesh->num_detached_states++;
+		mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c);
+	}
+}
--- contrib/unbound/services/mesh.h.orig
+++ contrib/unbound/services/mesh.h
@@ -51,6 +51,8 @@
 #include "util/data/msgparse.h"
 #include "util/module.h"
 #include "services/modstack.h"
+#include "services/rpz.h"
+#include "libunbound/unbound.h"
 struct sldns_buffer;
 struct mesh_state;
 struct mesh_reply;
@@ -65,7 +67,7 @@
  * Maximum number of mesh state activations. Any more is likely an
  * infinite loop in the module. It is then terminated.
  */
-#define MESH_MAX_ACTIVATION 3000
+#define MESH_MAX_ACTIVATION 10000
 
 /**
  * Max number of references-to-references-to-references.. search size.
@@ -110,6 +112,8 @@
 	size_t stats_jostled;
 	/** stats, cumulative number of incoming client msgs dropped */
 	size_t stats_dropped;
+	/** stats, number of expired replies sent */
+	size_t ans_expired;
 	/** number of replies sent */
 	size_t replies_sent;
 	/** sum of waiting times for the replies */
@@ -121,9 +125,11 @@
 	/** (extended stats) bogus replies */
 	size_t ans_bogus;
 	/** (extended stats) rcodes in replies */
-	size_t ans_rcode[16];
+	size_t ans_rcode[UB_STATS_RCODE_NUM];
 	/** (extended stats) rcode nodata in replies */
 	size_t ans_nodata;
+	/** (extended stats) type of applied RPZ action */
+	size_t rpz_action[UB_STATS_RPZ_ACTION_NUM];
 
 	/** backup of query if other operations recurse and need the
 	 * network buffers */
@@ -142,6 +148,11 @@
 	struct mesh_state* jostle_last;
 	/** timeout for jostling. if age is lower, it does not get jostled. */
 	struct timeval jostle_max;
+
+	/** If we need to use response ip (value passed from daemon)*/
+	int use_response_ip;
+	/** If we need to use RPZ (value passed from daemon) */
+	int use_rpz;
 };
 
 /**
@@ -633,4 +644,32 @@
 void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
 	struct mesh_state** lp);
 
+/**
+ * Remove mesh reply entry from the reply entry list.  Searches for
+ * the comm_point pointer.
+ * @param mesh: to update the counters.
+ * @param m: the mesh state.
+ * @param cp: the comm_point to remove from the list.
+ */
+void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
+	struct comm_point* cp);
+
+/** Callback for when the serve expired client timer has run out.  Tries to
+ * find an expired answer in the cache and reply that to the client.
+ * @param arg: the argument passed to the callback.
+ */
+void mesh_serve_expired_callback(void* arg);
+
+/**
+ * Try to get a (expired) cached answer.
+ * This needs to behave like the worker's answer_from_cache() in order to have
+ * the same behavior as when replying from cache.
+ * @param qstate: the module qstate.
+ * @param lookup_qinfo: the query info to look for in the cache.
+ * @return dns_msg if a cached answer was found, otherwise NULL.
+ */
+struct dns_msg*
+mesh_serve_expired_lookup(struct module_qstate* qstate,
+	struct query_info* lookup_qinfo);
+
 #endif /* SERVICES_MESH_H */
--- contrib/unbound/services/modstack.c.orig
+++ contrib/unbound/services/modstack.c
@@ -60,6 +60,9 @@
 #ifdef CLIENT_SUBNET
 #include "edns-subnet/subnetmod.h"
 #endif
+#ifdef USE_IPSET
+#include "ipset/ipset.h"
+#endif
 
 /** count number of modules (words) in the string */
 static int
@@ -113,8 +116,14 @@
         for(i=0; i<stack->num; i++) {
                 stack->mod[i] = module_factory(&module_conf);
                 if(!stack->mod[i]) {
-                        log_err("Unknown value for next module: '%s'",
-                                module_conf);
+			char md[256];
+			snprintf(md, sizeof(md), "%s", module_conf);
+			if(strchr(md, ' ')) *(strchr(md, ' ')) = 0;
+			if(strchr(md, '\t')) *(strchr(md, '\t')) = 0;
+                        log_err("Unknown value in module-config, module: '%s'."
+				" This module is not present (not compiled in),"
+				" See the list of linked modules with unbound -h",
+                                md);
                         return 0;
                 }
         }
@@ -140,6 +149,9 @@
 #ifdef CLIENT_SUBNET
 		"subnetcache",
 #endif
+#ifdef USE_IPSET
+                "ipset",
+#endif
 		"respip",
 		"validator",
 		"iterator",
@@ -168,6 +180,9 @@
 #ifdef CLIENT_SUBNET
 		&subnetmod_get_funcblock,
 #endif
+#ifdef USE_IPSET
+		&ipset_get_funcblock,
+#endif
 		&respip_get_funcblock,
 		&val_get_funcblock,
 		&iter_get_funcblock,
--- contrib/unbound/services/outside_network.c.orig
+++ contrib/unbound/services/outside_network.c
@@ -63,6 +63,9 @@
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
 #endif
+#ifdef HAVE_X509_VERIFY_PARAM_SET1_HOST
+#include <openssl/x509v3.h>
+#endif
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -290,6 +293,9 @@
 	/* open socket */
 	s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss);
 
+	if(s == -1)
+		return 0;
+
 	if(!pick_outgoing_tcp(w, s))
 		return 0;
 
@@ -361,6 +367,8 @@
 			comm_point_close(pend->c);
 			return 0;
 		}
+		verbose(VERB_ALGO, "the query is using TLS encryption, for %s",
+			(w->tls_auth_name?w->tls_auth_name:"an unauthenticated connection"));
 #ifdef USE_WINSOCK
 		comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
 #endif
@@ -385,6 +393,24 @@
 				return 0;
 			}
 		}
+#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
+		/* openssl 1.0.2 has this function that can be used for
+		 * set1_host like verification */
+		if(w->tls_auth_name) {
+			X509_VERIFY_PARAM* param = SSL_get0_param(pend->c->ssl);
+			X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+			if(!X509_VERIFY_PARAM_set1_host(param, w->tls_auth_name, strlen(w->tls_auth_name))) {
+				log_err("X509_VERIFY_PARAM_set1_host failed");
+				pend->c->fd = s;
+				SSL_free(pend->c->ssl);
+				pend->c->ssl = NULL;
+				comm_point_close(pend->c);
+				return 0;
+			}
+			SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
+		}
+#else
+		verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication");
 #endif /* HAVE_SSL_SET1_HOST */
 	}
 	w->pkt = NULL;
@@ -759,7 +785,7 @@
 		outnet->delay_tv.tv_usec = (delayclose%1000)*1000;
 	}
 #endif
-	if(numavailports == 0) {
+	if(numavailports == 0 || num_ports == 0) {
 		log_err("no outgoing ports available");
 		outside_network_delete(outnet);
 		return NULL;
@@ -1487,7 +1513,6 @@
 		/* clear up the pending query */
 		if(sq->status == serviced_query_UDP_EDNS ||
 			sq->status == serviced_query_UDP ||
-			sq->status == serviced_query_PROBE_EDNS ||
 			sq->status == serviced_query_UDP_EDNS_FRAG ||
 			sq->status == serviced_query_UDP_EDNS_fallback) {
 			struct pending* p = (struct pending*)sq->pending;
@@ -1614,15 +1639,7 @@
 	sq->last_rtt = rtt;
 	verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs);
 	if(sq->status == serviced_initial) {
-		if(edns_lame_known == 0 && rtt > 5000 && rtt < 10001) {
-			/* perform EDNS lame probe - check if server is
-			 * EDNS lame (EDNS queries to it are dropped) */
-			verbose(VERB_ALGO, "serviced query: send probe to see "
-				" if use of EDNS causes timeouts");
-			/* even 700 msec may be too small */
-			rtt = 1000;
-			sq->status = serviced_query_PROBE_EDNS;
-		} else if(vs != -1) {
+		if(vs != -1) {
 			sq->status = serviced_query_UDP_EDNS;
 		} else { 	
 			sq->status = serviced_query_UDP; 
@@ -1876,7 +1893,7 @@
 	if(!sq->pending) {
 		/* delete from tree so that a retry by above layer does not
 		 * clash with this entry */
-		log_err("serviced_tcp_initiate: failed to send tcp query");
+		verbose(VERB_ALGO, "serviced_tcp_initiate: failed to send tcp query");
 		serviced_callbacks(sq, NETEVENT_CLOSED, NULL, NULL);
 	}
 }
@@ -1954,17 +1971,9 @@
 	struct serviced_query* sq = (struct serviced_query*)arg;
 	struct outside_network* outnet = sq->outnet;
 	struct timeval now = *sq->outnet->now_tv;
-	int fallback_tcp = 0;
 
 	sq->pending = NULL; /* removed after callback */
 	if(error == NETEVENT_TIMEOUT) {
-		int rto = 0;
-		if(sq->status == serviced_query_PROBE_EDNS) {
-			/* non-EDNS probe failed; we do not know its status,
-			 * keep trying with EDNS, timeout may not be caused
-			 * by EDNS. */
-			sq->status = serviced_query_UDP_EDNS;
-		}
 		if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
 			/* fallback to 1480/1280 */
 			sq->status = serviced_query_UDP_EDNS_FRAG;
@@ -1980,9 +1989,9 @@
 			sq->status = serviced_query_UDP_EDNS;
 		}
 		sq->retry++;
-		if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
+		if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
 			sq->zone, sq->zonelen, sq->qtype, -1, sq->last_rtt,
-			(time_t)now.tv_sec)))
+			(time_t)now.tv_sec))
 			log_err("out of memory in UDP exponential backoff");
 		if(sq->retry < OUTBOUND_UDP_RETRY) {
 			log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10,
@@ -1992,14 +2001,8 @@
 			}
 			return 0;
 		}
-		if(rto >= RTT_MAX_TIMEOUT) {
-			/* fallback_tcp = 1; */
-			/* UDP does not work, fallback to TCP below */
-		} else {
-			serviced_callbacks(sq, NETEVENT_TIMEOUT, c, rep);
-			return 0;
-		}
-	} else if(error != NETEVENT_NOERROR) {
+	}
+	if(error != NETEVENT_NOERROR) {
 		/* udp returns error (due to no ID or interface available) */
 		serviced_callbacks(sq, error, c, rep);
 		return 0;
@@ -2012,9 +2015,8 @@
 		sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
 		&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
 #endif
-	if(!fallback_tcp) {
-	    if( (sq->status == serviced_query_UDP_EDNS 
-	        ||sq->status == serviced_query_UDP_EDNS_FRAG)
+	if( (sq->status == serviced_query_UDP_EDNS 
+		||sq->status == serviced_query_UDP_EDNS_FRAG)
 		&& (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) 
 			== LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(
 			sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL
@@ -2028,19 +2030,7 @@
 			serviced_callbacks(sq, NETEVENT_CLOSED, c, rep);
 		}
 		return 0;
-	    } else if(sq->status == serviced_query_PROBE_EDNS) {
-		/* probe without EDNS succeeds, so we conclude that this
-		 * host likely has EDNS packets dropped */
-		log_addr(VERB_DETAIL, "timeouts, concluded that connection to "
-			"host drops EDNS packets", &sq->addr, sq->addrlen);
-		/* only store noEDNS in cache if domain is noDNSSEC */
-		if(!sq->want_dnssec)
-		  if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
-			sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) {
-			log_err("Out of memory caching no edns for host");
-		  }
-		sq->status = serviced_query_UDP;
-	    } else if(sq->status == serviced_query_UDP_EDNS && 
+	} else if(sq->status == serviced_query_UDP_EDNS && 
 		!sq->edns_lame_known) {
 		/* now we know that edns queries received answers store that */
 		log_addr(VERB_ALGO, "serviced query: EDNS works for",
@@ -2050,7 +2040,7 @@
 			log_err("Out of memory caching edns works");
 		}
 		sq->edns_lame_known = 1;
-	    } else if(sq->status == serviced_query_UDP_EDNS_fallback &&
+	} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
 		!sq->edns_lame_known && (LDNS_RCODE_WIRE(
 		sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR || 
 		LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) == 
@@ -2068,12 +2058,12 @@
 		  }
 		} else {
 		  log_addr(VERB_ALGO, "serviced query: EDNS fails, but "
-		  	"not stored because need DNSSEC for", &sq->addr,
+			"not stored because need DNSSEC for", &sq->addr,
 			sq->addrlen);
 		}
 		sq->status = serviced_query_UDP;
-	    }
-	    if(now.tv_sec > sq->last_sent_time.tv_sec ||
+	}
+	if(now.tv_sec > sq->last_sent_time.tv_sec ||
 		(now.tv_sec == sq->last_sent_time.tv_sec &&
 		now.tv_usec > sq->last_sent_time.tv_usec)) {
 		/* convert from microseconds to milliseconds */
@@ -2089,11 +2079,10 @@
 			sq->last_rtt, (time_t)now.tv_sec))
 			log_err("out of memory noting rtt.");
 		}
-	    }
-	} /* end of if_!fallback_tcp */
+	}
 	/* perform TC flag check and TCP fallback after updating our
 	 * cache entries for EDNS status and RTT times */
-	if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer)) || fallback_tcp) {
+	if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer))) {
 		/* fallback to TCP */
 		/* this discards partial UDP contents */
 		if(sq->status == serviced_query_UDP_EDNS ||
@@ -2147,9 +2136,7 @@
 		if(outnet->do_udp && !(tcp_upstream || ssl_upstream)) {
 			if(!serviced_udp_send(sq, buff)) {
 				(void)rbtree_delete(outnet->serviced, sq);
-				free(sq->qbuf);
-				free(sq->zone);
-				free(sq);
+				serviced_node_del(&sq->node, NULL);
 				free(cb);
 				return NULL;
 			}
@@ -2156,9 +2143,7 @@
 		} else {
 			if(!serviced_tcp_send(sq, buff)) {
 				(void)rbtree_delete(outnet->serviced, sq);
-				free(sq->qbuf);
-				free(sq->zone);
-				free(sq);
+				serviced_node_del(&sq->node, NULL);
 				free(cb);
 				return NULL;
 			}
@@ -2294,11 +2279,60 @@
 	return cp;
 }
 
+/** setup SSL for comm point */
+static int
+setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
+	int fd, char* host)
+{
+	cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
+	if(!cp->ssl) {
+		log_err("cannot create SSL object");
+		return 0;
+	}
+#ifdef USE_WINSOCK
+	comm_point_tcp_win_bio_cb(cp, cp->ssl);
+#endif
+	cp->ssl_shake_state = comm_ssl_shake_write;
+	/* https verification */
+#ifdef HAVE_SSL_SET1_HOST
+	if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
+		/* because we set SSL_VERIFY_PEER, in netevent in
+		 * ssl_handshake, it'll check if the certificate
+		 * verification has succeeded */
+		/* SSL_VERIFY_PEER is set on the sslctx */
+		/* and the certificates to verify with are loaded into
+		 * it with SSL_load_verify_locations or
+		 * SSL_CTX_set_default_verify_paths */
+		/* setting the hostname makes openssl verify the
+		 * host name in the x509 certificate in the
+		 * SSL connection*/
+		if(!SSL_set1_host(cp->ssl, host)) {
+			log_err("SSL_set1_host failed");
+			return 0;
+		}
+	}
+#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
+	/* openssl 1.0.2 has this function that can be used for
+	 * set1_host like verification */
+	if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
+		X509_VERIFY_PARAM* param = SSL_get0_param(cp->ssl);
+		X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+		if(!X509_VERIFY_PARAM_set1_host(param, host, strlen(host))) {
+			log_err("X509_VERIFY_PARAM_set1_host failed");
+			return 0;
+		}
+	}
+#else
+	(void)host;
+#endif /* HAVE_SSL_SET1_HOST */
+	return 1;
+}
+
 struct comm_point*
 outnet_comm_point_for_tcp(struct outside_network* outnet,
 	comm_point_callback_type* cb, void* cb_arg,
 	struct sockaddr_storage* to_addr, socklen_t to_addrlen,
-	sldns_buffer* query, int timeout)
+	sldns_buffer* query, int timeout, int ssl, char* host)
 {
 	struct comm_point* cp;
 	int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
@@ -2318,6 +2352,16 @@
 	}
 	cp->repinfo.addrlen = to_addrlen;
 	memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
+
+	/* setup for SSL (if needed) */
+	if(ssl) {
+		if(!setup_comm_ssl(cp, outnet, fd, host)) {
+			log_err("cannot setup XoT");
+			comm_point_delete(cp);
+			return NULL;
+		}
+	}
+
 	/* set timeout on TCP connection */
 	comm_point_start_listening(cp, fd, timeout);
 	/* copy scratch buffer to cp->buffer */
@@ -2374,36 +2418,11 @@
 
 	/* setup for SSL (if needed) */
 	if(ssl) {
-		cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
-		if(!cp->ssl) {
+		if(!setup_comm_ssl(cp, outnet, fd, host)) {
 			log_err("cannot setup https");
 			comm_point_delete(cp);
 			return NULL;
 		}
-#ifdef USE_WINSOCK
-		comm_point_tcp_win_bio_cb(cp, cp->ssl);
-#endif
-		cp->ssl_shake_state = comm_ssl_shake_write;
-		/* https verification */
-#ifdef HAVE_SSL_SET1_HOST
-		if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
-			/* because we set SSL_VERIFY_PEER, in netevent in
-			 * ssl_handshake, it'll check if the certificate
-			 * verification has succeeded */
-			/* SSL_VERIFY_PEER is set on the sslctx */
-			/* and the certificates to verify with are loaded into
-			 * it with SSL_load_verify_locations or
-			 * SSL_CTX_set_default_verify_paths */
-			/* setting the hostname makes openssl verify the
-			 * host name in the x509 certificate in the
-			 * SSL connection*/
-		 	if(!SSL_set1_host(cp->ssl, host)) {
-				log_err("SSL_set1_host failed");
-				comm_point_delete(cp);
-				return NULL;
-			}
-		}
-#endif /* HAVE_SSL_SET1_HOST */
 	}
 
 	/* set timeout on TCP connection */
@@ -2508,7 +2527,6 @@
 		s += sizeof(*sb);
 	if(sq->status == serviced_query_UDP_EDNS ||
 		sq->status == serviced_query_UDP ||
-		sq->status == serviced_query_PROBE_EDNS ||
 		sq->status == serviced_query_UDP_EDNS_FRAG ||
 		sq->status == serviced_query_UDP_EDNS_fallback) {
 		s += sizeof(struct pending);
--- contrib/unbound/services/outside_network.h.orig
+++ contrib/unbound/services/outside_network.h
@@ -359,8 +359,6 @@
 		serviced_query_TCP_EDNS,
 		/** TCP without EDNS sent */
 		serviced_query_TCP,
-		/** probe to test EDNS lameness (EDNS is dropped) */
-		serviced_query_PROBE_EDNS,
 		/** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */
 		serviced_query_UDP_EDNS_fallback,
 		/** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */
@@ -572,12 +570,14 @@
  * @param timeout: timeout for the TCP connection.
  * 	timeout in milliseconds, or -1 for no (change to the) timeout.
  *	So seconds*1000.
+ * @param ssl: set to true for TLS.
+ * @param host: hostname for host name verification of TLS (or NULL if no TLS).
  * @return tcp_out commpoint, or NULL.
  */
 struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
 	comm_point_callback_type* cb, void* cb_arg,
 	struct sockaddr_storage* to_addr, socklen_t to_addrlen,
-	struct sldns_buffer* query, int timeout);
+	struct sldns_buffer* query, int timeout, int ssl, char* host);
 
 /**
  * Create http commpoint suitable for communication to the destination.
--- contrib/unbound/services/rpz.c.orig
+++ contrib/unbound/services/rpz.c
@@ -0,0 +1,1015 @@
+/*
+ * services/rpz.c - rpz service
+ *
+ * Copyright (c) 2019, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains functions to enable RPZ service.
+ */
+
+#include "config.h"
+#include "services/rpz.h"
+#include "util/config_file.h"
+#include "sldns/wire2str.h"
+#include "sldns/str2wire.h"
+#include "util/data/dname.h"
+#include "util/net_help.h"
+#include "util/log.h"
+#include "util/data/dname.h"
+#include "util/locks.h"
+#include "util/regional.h"
+
+/** string for RPZ action enum */
+const char*
+rpz_action_to_string(enum rpz_action a)
+{
+	switch(a) {
+	case RPZ_NXDOMAIN_ACTION:	return "nxdomain";
+	case RPZ_NODATA_ACTION:		return "nodata";
+	case RPZ_PASSTHRU_ACTION:	return "passthru";
+	case RPZ_DROP_ACTION:		return "drop";
+	case RPZ_TCP_ONLY_ACTION:	return "tcp_only";
+	case RPZ_INVALID_ACTION:	return "invalid";
+	case RPZ_LOCAL_DATA_ACTION:	return "local_data";
+	case RPZ_DISABLED_ACTION:	return "disabled";
+	case RPZ_CNAME_OVERRIDE_ACTION:	return "cname_override";
+	case RPZ_NO_OVERRIDE_ACTION:	return "no_override";
+	}
+	return "unknown";
+}
+
+/** RPZ action enum for config string */
+static enum rpz_action
+rpz_config_to_action(char* a)
+{
+	if(strcmp(a, "nxdomain") == 0)
+		return RPZ_NXDOMAIN_ACTION;
+	else if(strcmp(a, "nodata") == 0)
+		return RPZ_NODATA_ACTION;
+	else if(strcmp(a, "passthru") == 0)
+		return RPZ_PASSTHRU_ACTION;
+	else if(strcmp(a, "drop") == 0)
+		return RPZ_DROP_ACTION;
+	else if(strcmp(a, "tcp_only") == 0)
+		return RPZ_TCP_ONLY_ACTION;
+	else if(strcmp(a, "cname") == 0)
+		return RPZ_CNAME_OVERRIDE_ACTION;
+	else if(strcmp(a, "disabled") == 0)
+		return RPZ_DISABLED_ACTION;
+	return RPZ_INVALID_ACTION;
+}
+
+/** string for RPZ trigger enum */
+static const char*
+rpz_trigger_to_string(enum rpz_trigger r)
+{
+	switch(r) {
+	case RPZ_QNAME_TRIGGER:		return "qname";
+	case RPZ_CLIENT_IP_TRIGGER:	return "client_ip";
+	case RPZ_RESPONSE_IP_TRIGGER:	return "response_ip";
+	case RPZ_NSDNAME_TRIGGER:	return "nsdname";
+	case RPZ_NSIP_TRIGGER:		return "nsip";
+	case RPZ_INVALID_TRIGGER:	return "invalid";
+	}
+	return "unknown";
+}
+
+/**
+ * Get the label that is just before the root label.
+ * @param dname: dname to work on
+ * @param maxdnamelen: maximum length of the dname
+ * @return: pointer to TLD label, NULL if not found or invalid dname
+ */
+static uint8_t*
+get_tld_label(uint8_t* dname, size_t maxdnamelen)
+{
+	uint8_t* prevlab = dname;
+	size_t dnamelen = 0;
+
+	/* one byte needed for label length */
+	if(dnamelen+1 > maxdnamelen)
+		return NULL;
+
+	/* only root label */
+	if(*dname == 0)
+		return NULL;
+
+	while(*dname) {
+		dnamelen += ((size_t)*dname)+1;
+		if(dnamelen+1 > maxdnamelen)
+			return NULL;
+		dname = dname+((size_t)*dname)+1;
+		if(*dname != 0)
+			prevlab = dname;
+	}
+	return prevlab;
+}
+
+/**
+ * Classify RPZ action for RR type/rdata
+ * @param rr_type: the RR type
+ * @param rdatawl: RDATA with 2 bytes length
+ * @param rdatalen: the length of rdatawl (including its 2 bytes length)
+ * @return: the RPZ action
+ */
+static enum rpz_action
+rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
+{
+	char* endptr;
+	uint8_t* rdata;
+	int rdatalabs;
+	uint8_t* tldlab = NULL;
+
+	switch(rr_type) {
+		case LDNS_RR_TYPE_SOA:
+		case LDNS_RR_TYPE_NS:
+		case LDNS_RR_TYPE_DNAME:
+		/* all DNSSEC-related RRs must be ignored */
+		case LDNS_RR_TYPE_DNSKEY:
+		case LDNS_RR_TYPE_DS:
+		case LDNS_RR_TYPE_RRSIG:
+		case LDNS_RR_TYPE_NSEC:
+		case LDNS_RR_TYPE_NSEC3:
+			return RPZ_INVALID_ACTION;
+		case LDNS_RR_TYPE_CNAME:
+			break;
+		default:
+			return RPZ_LOCAL_DATA_ACTION;
+	}
+
+	/* use CNAME target to determine RPZ action */
+	log_assert(rr_type == LDNS_RR_TYPE_CNAME);
+	if(rdatalen < 3)
+		return RPZ_INVALID_ACTION;
+
+	rdata = rdatawl + 2; /* 2 bytes of rdata length */
+	if(dname_valid(rdata, rdatalen-2) != rdatalen-2)
+		return RPZ_INVALID_ACTION;
+
+	rdatalabs = dname_count_labels(rdata);
+	if(rdatalabs == 1)
+		return RPZ_NXDOMAIN_ACTION;
+	else if(rdatalabs == 2) {
+		if(dname_subdomain_c(rdata, (uint8_t*)&"\001*\000"))
+			return RPZ_NODATA_ACTION;
+		else if(dname_subdomain_c(rdata,
+			(uint8_t*)&"\014rpz-passthru\000"))
+			return RPZ_PASSTHRU_ACTION;
+		else if(dname_subdomain_c(rdata, (uint8_t*)&"\010rpz-drop\000"))
+			return RPZ_DROP_ACTION;
+		else if(dname_subdomain_c(rdata,
+			(uint8_t*)&"\014rpz-tcp-only\000"))
+			return RPZ_TCP_ONLY_ACTION;
+	}
+
+	/* all other TLDs starting with "rpz-" are invalid */
+	tldlab = get_tld_label(rdata, rdatalen-2);
+	if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr))
+		return RPZ_INVALID_ACTION;
+
+	/* no special label found */
+	return RPZ_LOCAL_DATA_ACTION;
+}
+
+static enum localzone_type 
+rpz_action_to_localzone_type(enum rpz_action a)
+{
+	switch(a) {
+	case RPZ_NXDOMAIN_ACTION:	return local_zone_always_nxdomain;
+	case RPZ_NODATA_ACTION:		return local_zone_always_nodata;
+	case RPZ_DROP_ACTION:		return local_zone_always_deny;
+	case RPZ_PASSTHRU_ACTION:	return local_zone_always_transparent;
+	case RPZ_LOCAL_DATA_ACTION:	/* fallthrough */
+	case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
+	case RPZ_INVALID_ACTION: 	/* fallthrough */
+	case RPZ_TCP_ONLY_ACTION:	/* fallthrough */
+	default:			return local_zone_invalid;
+	}
+}
+
+enum respip_action
+rpz_action_to_respip_action(enum rpz_action a)
+{
+	switch(a) {
+	case RPZ_NXDOMAIN_ACTION:	return respip_always_nxdomain;
+	case RPZ_NODATA_ACTION:		return respip_always_nodata;
+	case RPZ_DROP_ACTION:		return respip_always_deny;
+	case RPZ_PASSTHRU_ACTION:	return respip_always_transparent;
+	case RPZ_LOCAL_DATA_ACTION:	/* fallthrough */
+	case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
+	case RPZ_INVALID_ACTION:	/* fallthrough */
+	case RPZ_TCP_ONLY_ACTION:	/* fallthrough */
+	default:			return respip_invalid;
+	}
+}
+
+static enum rpz_action
+localzone_type_to_rpz_action(enum localzone_type lzt)
+{
+	switch(lzt) {
+	case local_zone_always_nxdomain:	return RPZ_NXDOMAIN_ACTION;
+	case local_zone_always_nodata:		return RPZ_NODATA_ACTION;
+	case local_zone_always_deny:		return RPZ_DROP_ACTION;
+	case local_zone_always_transparent:	return RPZ_PASSTHRU_ACTION;
+	case local_zone_redirect:		return RPZ_LOCAL_DATA_ACTION;
+	case local_zone_invalid:
+	default:
+		return RPZ_INVALID_ACTION;
+	}
+}
+
+enum rpz_action
+respip_action_to_rpz_action(enum respip_action a)
+{
+	switch(a) {
+	case respip_always_nxdomain:	return RPZ_NXDOMAIN_ACTION;
+	case respip_always_nodata:	return RPZ_NODATA_ACTION;
+	case respip_always_deny:	return RPZ_DROP_ACTION;
+	case respip_always_transparent:	return RPZ_PASSTHRU_ACTION;
+	case respip_redirect:		return RPZ_LOCAL_DATA_ACTION;
+	case respip_invalid:
+	default:
+		return RPZ_INVALID_ACTION;
+	}
+}
+
+/**
+ * Get RPZ trigger for dname
+ * @param dname: dname containing RPZ trigger
+ * @param dname_len: length of the dname
+ * @return: RPZ trigger enum
+ */
+static enum rpz_trigger
+rpz_dname_to_trigger(uint8_t* dname, size_t dname_len)
+{
+	uint8_t* tldlab;
+	char* endptr;
+
+	if(dname_valid(dname, dname_len) != dname_len)
+		return RPZ_INVALID_TRIGGER;
+
+	tldlab = get_tld_label(dname, dname_len);
+	if(!tldlab || !dname_lab_startswith(tldlab, "rpz-", &endptr))
+		return RPZ_QNAME_TRIGGER;
+
+	if(dname_subdomain_c(tldlab,
+		(uint8_t*)&"\015rpz-client-ip\000"))
+		return RPZ_CLIENT_IP_TRIGGER;
+	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\006rpz-ip\000"))
+		return RPZ_RESPONSE_IP_TRIGGER;
+	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\013rpz-nsdname\000"))
+		return RPZ_NSDNAME_TRIGGER;
+	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\010rpz-nsip\000"))
+		return RPZ_NSIP_TRIGGER;
+
+	return RPZ_QNAME_TRIGGER;
+}
+
+void rpz_delete(struct rpz* r)
+{
+	if(!r)
+		return;
+	local_zones_delete(r->local_zones);
+	respip_set_delete(r->respip_set);
+	regional_destroy(r->region);
+	free(r->taglist);
+	free(r->log_name);
+	free(r);
+}
+
+int
+rpz_clear(struct rpz* r)
+{
+	/* must hold write lock on auth_zone */
+	local_zones_delete(r->local_zones);
+	respip_set_delete(r->respip_set);
+	if(!(r->local_zones = local_zones_create())){
+		return 0;
+	}
+	if(!(r->respip_set = respip_set_create())) {
+		return 0;
+	}
+	return 1;
+}
+
+void
+rpz_finish_config(struct rpz* r)
+{
+	lock_rw_wrlock(&r->respip_set->lock);
+	addr_tree_init_parents(&r->respip_set->ip_tree);
+	lock_rw_unlock(&r->respip_set->lock);
+}
+
+/** new rrset containing CNAME override, does not yet contain a dname */
+static struct ub_packed_rrset_key*
+new_cname_override(struct regional* region, uint8_t* ct, size_t ctlen)
+{
+	struct ub_packed_rrset_key* rrset;
+	struct packed_rrset_data* pd;
+	uint16_t rdlength = htons(ctlen);
+	rrset = (struct ub_packed_rrset_key*)regional_alloc_zero(region,
+		sizeof(*rrset));
+	if(!rrset) {
+		log_err("out of memory");
+		return NULL;
+	}
+	rrset->entry.key = rrset;
+	pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
+	if(!pd) {
+		log_err("out of memory");
+		return NULL;
+	}
+	pd->trust = rrset_trust_prim_noglue;
+	pd->security = sec_status_insecure;
+
+	pd->count = 1;
+	pd->rr_len = regional_alloc_zero(region, sizeof(*pd->rr_len));
+	pd->rr_ttl = regional_alloc_zero(region, sizeof(*pd->rr_ttl));
+	pd->rr_data = regional_alloc_zero(region, sizeof(*pd->rr_data));
+	if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
+		log_err("out of memory");
+		return NULL;
+	}
+	pd->rr_len[0] = ctlen+2;
+	pd->rr_ttl[0] = 3600;
+	pd->rr_data[0] = regional_alloc_zero(region, 2 /* rdlength */ + ctlen);
+	if(!pd->rr_data[0]) {
+		log_err("out of memory");
+		return NULL;
+	}
+	memmove(pd->rr_data[0], &rdlength, 2);
+	memmove(pd->rr_data[0]+2, ct, ctlen);
+
+	rrset->entry.data = pd;
+	rrset->rk.type = htons(LDNS_RR_TYPE_CNAME);
+	rrset->rk.rrset_class = htons(LDNS_RR_CLASS_IN);
+	return rrset;
+}
+
+struct rpz*
+rpz_create(struct config_auth* p)
+{
+	struct rpz* r = calloc(1, sizeof(*r));
+	if(!r)
+		goto err;
+
+	r->region = regional_create_custom(sizeof(struct regional));
+	if(!r->region) {
+		goto err;
+	}
+
+	if(!(r->local_zones = local_zones_create())){
+		goto err;
+	}
+	if(!(r->respip_set = respip_set_create())) {
+		goto err;
+	}
+	r->taglistlen = p->rpz_taglistlen;
+	r->taglist = memdup(p->rpz_taglist, r->taglistlen);
+	if(p->rpz_action_override) {
+		r->action_override = rpz_config_to_action(p->rpz_action_override);
+	}
+	else
+		r->action_override = RPZ_NO_OVERRIDE_ACTION;
+
+	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
+		uint8_t nm[LDNS_MAX_DOMAINLEN+1];
+		size_t nmlen = sizeof(nm);
+
+		if(!p->rpz_cname) {
+			log_err("RPZ override with cname action found, but no "
+				"rpz-cname-override configured");
+			goto err;
+		}
+
+		if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) {
+			log_err("cannot parse RPZ cname override: %s",
+				p->rpz_cname);
+			goto err;
+		}
+		r->cname_override = new_cname_override(r->region, nm, nmlen);
+		if(!r->cname_override) {
+			goto err;
+		}
+	}
+	r->log = p->rpz_log;
+	if(p->rpz_log_name) {
+		if(!(r->log_name = strdup(p->rpz_log_name))) {
+			log_err("malloc failure on RPZ log_name strdup");
+			goto err;
+		}
+	}
+	return r;
+err:
+	if(r) {
+		if(r->local_zones)
+			local_zones_delete(r->local_zones);
+		if(r->respip_set)
+			respip_set_delete(r->respip_set);
+		if(r->taglist)
+			free(r->taglist);
+		free(r);
+	}
+	return NULL;
+}
+
+/**
+ * Remove RPZ zone name from dname
+ * Copy dname to newdname, without the originlen number of trailing bytes
+ */
+static size_t
+strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
+	uint8_t* newdname, size_t maxnewdnamelen)
+{
+	size_t newdnamelen;
+	if(dnamelen < originlen)
+		return 0;
+	newdnamelen = dnamelen - originlen;
+	if(newdnamelen+1 > maxnewdnamelen)
+		return 0;
+	memmove(newdname, dname, newdnamelen);
+	newdname[newdnamelen] = 0;
+	return newdnamelen + 1;	/* + 1 for root label */
+}
+
+/** Insert RR into RPZ's local-zone */
+static void
+rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
+	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
+	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
+{
+	struct local_zone* z;
+	enum localzone_type tp = local_zone_always_transparent;
+	int dnamelabs = dname_count_labels(dname);
+	char* rrstr;
+	int newzone = 0;
+
+	if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION) {
+		verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
+			rpz_action_to_string(a));
+		free(dname);
+		return;
+	}
+
+	lock_rw_wrlock(&r->local_zones->lock);
+	/* exact match */
+	z = local_zones_find(r->local_zones, dname, dnamelen, dnamelabs,
+		LDNS_RR_CLASS_IN);
+	if(z && a != RPZ_LOCAL_DATA_ACTION) {
+		rrstr = sldns_wire2str_rr(rr, rr_len);
+		if(!rrstr) {
+			log_err("malloc error while inserting RPZ qname "
+				"trigger");
+			free(dname);
+			lock_rw_unlock(&r->local_zones->lock);
+			return;
+		}
+		verbose(VERB_ALGO, "RPZ: skipping duplicate record: '%s'",
+			rrstr);
+		free(rrstr);
+		free(dname);
+		lock_rw_unlock(&r->local_zones->lock);
+		return;
+	}
+	if(!z) {
+		tp = rpz_action_to_localzone_type(a);
+		if(!(z = local_zones_add_zone(r->local_zones, dname, dnamelen,
+			dnamelabs, rrclass, tp))) {
+			log_warn("RPZ create failed");
+			lock_rw_unlock(&r->local_zones->lock);
+			/* dname will be free'd in failed local_zone_create() */
+			return;
+		}
+		newzone = 1;
+	}
+	if(a == RPZ_LOCAL_DATA_ACTION) {
+		rrstr = sldns_wire2str_rr(rr, rr_len);
+		if(!rrstr) {
+			log_err("malloc error while inserting RPZ qname "
+				"trigger");
+			free(dname);
+			lock_rw_unlock(&r->local_zones->lock);
+			return;
+		}
+		lock_rw_wrlock(&z->lock);
+		local_zone_enter_rr(z, dname, dnamelen, dnamelabs,
+			rrtype, rrclass, ttl, rdata, rdata_len, rrstr);
+		lock_rw_unlock(&z->lock);
+		free(rrstr);
+	}
+	if(!newzone)
+		free(dname);
+	lock_rw_unlock(&r->local_zones->lock);
+	return;
+}
+
+/** Insert RR into RPZ's respip_set */
+static int
+rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
+	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
+	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
+{
+	struct resp_addr* node;
+	struct sockaddr_storage addr;
+	socklen_t addrlen;
+	int net, af;
+	char* rrstr;
+	enum respip_action respa = rpz_action_to_respip_action(a);
+
+	if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION ||
+		respa == respip_invalid) {
+		verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
+			rpz_action_to_string(a));
+		return 0;
+	}
+
+	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
+		return 0;
+
+	lock_rw_wrlock(&r->respip_set->lock);
+	rrstr = sldns_wire2str_rr(rr, rr_len);
+	if(!rrstr) {
+		log_err("malloc error while inserting RPZ respip trigger");
+		lock_rw_unlock(&r->respip_set->lock);
+		return 0;
+	}
+	if(!(node=respip_sockaddr_find_or_create(r->respip_set, &addr, addrlen,
+		net, 1, rrstr))) {
+		lock_rw_unlock(&r->respip_set->lock);
+		free(rrstr);
+		return 0;
+	}
+
+	lock_rw_wrlock(&node->lock);
+	lock_rw_unlock(&r->respip_set->lock);
+	node->action = respa;
+
+	if(a == RPZ_LOCAL_DATA_ACTION) {
+		respip_enter_rr(r->respip_set->region, node, rrtype,
+			rrclass, ttl, rdata, rdata_len, rrstr, "");
+	}
+	lock_rw_unlock(&node->lock);
+	free(rrstr);
+	return 1;
+}
+
+int
+rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
+	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
+	uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
+{
+	size_t policydnamelen;
+	/* name is free'd in local_zone delete */
+	enum rpz_trigger t;
+	enum rpz_action a;
+	uint8_t* policydname;
+
+	log_assert(dnamelen >= aznamelen);
+	if(!(policydname = calloc(1, (dnamelen-aznamelen)+1)))
+		return 0;
+
+	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
+	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
+		policydname, (dnamelen-aznamelen)+1))) {
+		free(policydname);
+		return 0;
+	}
+	t = rpz_dname_to_trigger(policydname, policydnamelen);
+	if(t == RPZ_INVALID_TRIGGER) {
+		free(policydname);
+		verbose(VERB_ALGO, "RPZ: skipping invalid trigger");
+		return 1;
+	}
+	if(t == RPZ_QNAME_TRIGGER) {
+		rpz_insert_qname_trigger(r, policydname, policydnamelen,
+			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
+			rr_len);
+	}
+	else if(t == RPZ_RESPONSE_IP_TRIGGER) {
+		rpz_insert_response_ip_trigger(r, policydname, policydnamelen,
+			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
+			rr_len);
+		free(policydname);
+	}
+	else {
+		free(policydname);
+		verbose(VERB_ALGO, "RPZ: skipping unsupported trigger: %s",
+			rpz_trigger_to_string(t));
+	}
+	return 1;
+}
+
+/**
+ * Find RPZ local-zone by qname.
+ * @param r: rpz containing local-zone tree
+ * @param qname: qname
+ * @param qname_len: length of qname
+ * @param qclass: qclass
+ * @param only_exact: if 1 only excact (non wildcard) matches are returned
+ * @param wr: get write lock for local-zone if 1, read lock if 0
+ * @param zones_keep_lock: if set do not release the r->local_zones lock, this
+ * 	  makes the caller of this function responsible for releasing the lock.
+ * @return: NULL or local-zone holding rd or wr lock
+ */
+static struct local_zone*
+rpz_find_zone(struct rpz* r, uint8_t* qname, size_t qname_len, uint16_t qclass,
+	int only_exact, int wr, int zones_keep_lock)
+{
+	uint8_t* ce;
+	size_t ce_len, ce_labs;
+	uint8_t wc[LDNS_MAX_DOMAINLEN+1];
+	int exact;
+	struct local_zone* z = NULL;
+	if(wr) {
+		lock_rw_wrlock(&r->local_zones->lock);
+	} else {
+		lock_rw_rdlock(&r->local_zones->lock);
+	}
+	z = local_zones_find_le(r->local_zones, qname, qname_len,
+		dname_count_labels(qname),
+		LDNS_RR_CLASS_IN, &exact);
+	if(!z || (only_exact && !exact)) {
+		lock_rw_unlock(&r->local_zones->lock);
+		return NULL;
+	}
+	if(wr) {
+		lock_rw_wrlock(&z->lock);
+	} else {
+		lock_rw_rdlock(&z->lock);
+	}
+	if(!zones_keep_lock) {
+		lock_rw_unlock(&r->local_zones->lock);
+	}
+
+	if(exact)
+		return z;
+
+	/* No exact match found, lookup wildcard. closest encloser must
+	 * be the shared parent between the qname and the best local
+	 * zone match, append '*' to that and do another lookup. */
+
+	ce = dname_get_shared_topdomain(z->name, qname);
+	if(!ce /* should not happen */ || !*ce /* root */) {
+		lock_rw_unlock(&z->lock);
+		if(zones_keep_lock) {
+			lock_rw_unlock(&r->local_zones->lock);
+		}
+		return NULL;
+	}
+	ce_labs = dname_count_size_labels(ce, &ce_len);
+	if(ce_len+2 > sizeof(wc)) {
+		lock_rw_unlock(&z->lock);
+		if(zones_keep_lock) {
+			lock_rw_unlock(&r->local_zones->lock);
+		}
+		return NULL;
+	}
+	wc[0] = 1; /* length of wildcard label */
+	wc[1] = (uint8_t)'*'; /* wildcard label */
+	memmove(wc+2, ce, ce_len);
+	lock_rw_unlock(&z->lock);
+
+	if(!zones_keep_lock) {
+		if(wr) {
+			lock_rw_wrlock(&r->local_zones->lock);
+		} else {
+			lock_rw_rdlock(&r->local_zones->lock);
+		}
+	}
+	z = local_zones_find_le(r->local_zones, wc,
+		ce_len+2, ce_labs+1, qclass, &exact);
+	if(!z || !exact) {
+		lock_rw_unlock(&r->local_zones->lock);
+		return NULL;
+	}
+	if(wr) {
+		lock_rw_wrlock(&z->lock);
+	} else {
+		lock_rw_rdlock(&z->lock);
+	}
+	if(!zones_keep_lock) {
+		lock_rw_unlock(&r->local_zones->lock);
+	}
+	return z;
+}
+
+/**
+ * Remove RR from RPZ's local-data
+ * @param z: local-zone for RPZ, holding write lock
+ * @param policydname: dname of RR to remove
+ * @param policydnamelen: lenth of policydname
+ * @param rr_type: RR type of RR to remove
+ * @param rdata: rdata of RR to remove
+ * @param rdatalen: length of rdata
+ * @return: 1 if zone must be removed after RR deletion
+ */
+static int
+rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname,
+	size_t policydnamelen, uint16_t rr_type, uint8_t* rdata,
+	size_t rdatalen)
+{
+	struct local_data* ld;
+	struct packed_rrset_data* d;
+	size_t index;
+	ld = local_zone_find_data(z, policydname, policydnamelen,
+		dname_count_labels(policydname));
+	if(ld) {
+		struct local_rrset* prev=NULL, *p=ld->rrsets;
+		while(p && ntohs(p->rrset->rk.type) != rr_type) {
+			prev = p;
+			p = p->next;
+		}
+		if(!p)
+			return 0;
+		d = (struct packed_rrset_data*)p->rrset->entry.data;
+		if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
+			if(d->count == 1) {
+				/* no memory recycling for zone deletions ... */
+				if(prev) prev->next = p->next;
+				else ld->rrsets = p->next;
+			}
+			if(d->count > 1) {
+				if(!local_rrset_remove_rr(d, index))
+					return 0;
+			}
+		}
+	}
+	if(ld && ld->rrsets)
+		return 0;
+	return 1;
+}
+
+/**
+ * Remove RR from RPZ's respip set
+ * @param raddr: respip node
+ * @param rr_type: RR type of RR to remove
+ * @param rdata: rdata of RR to remove
+ * @param rdatalen: length of rdata
+ * @return: 1 if zone must be removed after RR deletion
+ */
+static int
+rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata,
+	size_t rdatalen)
+{
+	size_t index;
+	struct packed_rrset_data* d;
+	if(!raddr->data)
+		return 1;
+	d = raddr->data->entry.data;
+	if(ntohs(raddr->data->rk.type) != rr_type) {
+		return 0;
+	}
+	if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
+		if(d->count == 1) {
+			/* regional alloc'd */
+			raddr->data->entry.data = NULL; 
+			raddr->data = NULL;
+			return 1;
+		}
+		if(d->count > 1) {
+			if(!local_rrset_remove_rr(d, index))
+				return 0;
+		}
+	}
+	return 0;
+
+}
+
+/** Remove RR from RPZ's local-zone */
+static void
+rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
+	enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
+	uint8_t* rdatawl, size_t rdatalen)
+{
+	struct local_zone* z;
+	int delete_zone = 1;
+	z = rpz_find_zone(r, dname, dnamelen, rr_class,
+		1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/);
+	if(!z) {
+		verbose(VERB_ALGO, "RPZ: cannot remove RR from IXFR, "
+			"RPZ domain not found");
+		return;
+	}
+	if(a == RPZ_LOCAL_DATA_ACTION)
+		delete_zone = rpz_data_delete_rr(z, dname,
+			dnamelen, rr_type, rdatawl, rdatalen);
+	else if(a != localzone_type_to_rpz_action(z->type)) {
+		return;
+	}
+	lock_rw_unlock(&z->lock); 
+	if(delete_zone) {
+		local_zones_del_zone(r->local_zones, z);
+	}
+	lock_rw_unlock(&r->local_zones->lock); 
+	return;
+}
+
+static void
+rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
+	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
+{
+	struct resp_addr* node;
+	struct sockaddr_storage addr;
+	socklen_t addrlen;
+	int net, af;
+	int delete_respip = 1;
+
+	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
+		return;
+
+	lock_rw_wrlock(&r->respip_set->lock);
+	if(!(node = (struct resp_addr*)addr_tree_find(
+		&r->respip_set->ip_tree, &addr, addrlen, net))) {
+		verbose(VERB_ALGO, "RPZ: cannot remove RR from IXFR, "
+			"RPZ domain not found");
+		lock_rw_unlock(&r->respip_set->lock);
+		return;
+	}
+
+	lock_rw_wrlock(&node->lock);
+	if(a == RPZ_LOCAL_DATA_ACTION) {
+		/* remove RR, signal whether RR can be removed */
+		delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl, 
+			rdatalen);
+	}
+	lock_rw_unlock(&node->lock);
+	if(delete_respip)
+		respip_sockaddr_delete(r->respip_set, node);
+	lock_rw_unlock(&r->respip_set->lock);
+}
+
+void
+rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, size_t dnamelen,
+	uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen)
+{
+	size_t policydnamelen;
+	enum rpz_trigger t;
+	enum rpz_action a;
+	uint8_t* policydname;
+
+	if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1)))
+		return;
+
+	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
+	if(a == RPZ_INVALID_ACTION) {
+		free(policydname);
+		return;
+	}
+	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
+		policydname, LDNS_MAX_DOMAINLEN + 1))) {
+		free(policydname);
+		return;
+	}
+	t = rpz_dname_to_trigger(policydname, policydnamelen);
+	if(t == RPZ_QNAME_TRIGGER) {
+		rpz_remove_qname_trigger(r, policydname, policydnamelen, a,
+			rr_type, rr_class, rdatawl, rdatalen);
+	} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
+		rpz_remove_response_ip_trigger(r, policydname, policydnamelen,
+			a, rr_type, rdatawl, rdatalen);
+	}
+	free(policydname);
+}
+
+/** print log information for an applied RPZ policy. Based on local-zone's
+ * lz_inform_print().
+ */
+static void
+log_rpz_apply(uint8_t* dname, enum rpz_action a, struct query_info* qinfo,
+	struct comm_reply* repinfo, char* log_name)
+{
+	char ip[128], txt[512];
+	char dnamestr[LDNS_MAX_DOMAINLEN+1];
+	uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
+	dname_str(dname, dnamestr);
+	addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
+	if(log_name)
+		snprintf(txt, sizeof(txt), "RPZ applied [%s] %s %s %s@%u",
+			log_name, dnamestr, rpz_action_to_string(a), ip,
+			(unsigned)port);
+	else
+		snprintf(txt, sizeof(txt), "RPZ applied %s %s %s@%u",
+			dnamestr, rpz_action_to_string(a), ip, (unsigned)port);
+	log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
+}
+
+int
+rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
+	struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
+	struct regional* temp, struct comm_reply* repinfo,
+	uint8_t* taglist, size_t taglen, struct ub_server_stats* stats)
+{
+	struct rpz* r;
+	int ret;
+	enum localzone_type lzt;
+	struct local_zone* z = NULL;
+	struct local_data* ld = NULL;
+	lock_rw_rdlock(&az->rpz_lock);
+	for(r = az->rpz_first; r; r = r->next) {
+		if(!r->taglist || taglist_intersect(r->taglist, 
+			r->taglistlen, taglist, taglen)) {
+			z = rpz_find_zone(r, qinfo->qname, qinfo->qname_len,
+				qinfo->qclass, 0, 0, 0);
+			if(z && r->action_override == RPZ_DISABLED_ACTION) {
+				if(r->log)
+					log_rpz_apply(z->name,
+						r->action_override,
+						qinfo, repinfo, r->log_name);
+				/* TODO only register stats when stats_extended?
+				 * */
+				stats->rpz_action[r->action_override]++;
+				lock_rw_unlock(&z->lock);
+				z = NULL;
+			}
+			if(z)
+				break;
+		}	
+	}
+	lock_rw_unlock(&az->rpz_lock);
+	if(!z)
+		return 0;
+
+	
+	if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
+		lzt = z->type;
+	else
+		lzt = rpz_action_to_localzone_type(r->action_override);
+
+	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
+		qinfo->local_alias =
+			regional_alloc_zero(temp, sizeof(struct local_rrset));
+		if(!qinfo->local_alias) {
+			lock_rw_unlock(&z->lock);
+			return 0; /* out of memory */
+		}
+		qinfo->local_alias->rrset =
+			regional_alloc_init(temp, r->cname_override,
+				sizeof(*r->cname_override));
+		if(!qinfo->local_alias->rrset) {
+			lock_rw_unlock(&z->lock);
+			return 0; /* out of memory */
+		}
+		qinfo->local_alias->rrset->rk.dname = qinfo->qname;
+		qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
+		if(r->log)
+			log_rpz_apply(z->name, RPZ_CNAME_OVERRIDE_ACTION, 
+				qinfo, repinfo, r->log_name);
+		stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
+		lock_rw_unlock(&z->lock);
+		return 0;
+	}
+
+	if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo,
+		edns, repinfo, buf, temp, dname_count_labels(qinfo->qname),
+		&ld, lzt, -1, NULL, 0, NULL, 0)) {
+		if(r->log)
+			log_rpz_apply(z->name,
+				localzone_type_to_rpz_action(lzt), qinfo,
+				repinfo, r->log_name);
+		stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
+		lock_rw_unlock(&z->lock);
+		return !qinfo->local_alias;
+	}
+
+	ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
+		0 /* no local data used */, lzt);
+	if(r->log)
+		log_rpz_apply(z->name, localzone_type_to_rpz_action(lzt),
+			qinfo, repinfo, r->log_name);
+	stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
+	lock_rw_unlock(&z->lock);
+
+	return ret;
+}
--- contrib/unbound/services/rpz.h.orig
+++ contrib/unbound/services/rpz.h
@@ -0,0 +1,201 @@
+/*
+ * services/rpz.h - rpz service
+ *
+ * Copyright (c) 2019, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains functions to enable RPZ service.
+ */
+
+#ifndef SERVICES_RPZ_H
+#define SERVICES_RPZ_H
+
+#include "services/localzone.h"
+#include "util/locks.h"
+#include "util/log.h"
+#include "util/config_file.h"
+#include "services/authzone.h"
+#include "sldns/sbuffer.h"
+#include "daemon/stats.h"
+#include "respip/respip.h"
+
+/**
+ * RPZ triggers, only the QNAME trigger is currently supported in Unbound.
+ */
+enum rpz_trigger {
+	RPZ_QNAME_TRIGGER = 0,
+	/* unsupported triggers */
+	RPZ_CLIENT_IP_TRIGGER,	 /* rpz-client-ip */
+	RPZ_RESPONSE_IP_TRIGGER, /* rpz-ip */
+	RPZ_NSDNAME_TRIGGER,	 /* rpz-nsdname */
+	RPZ_NSIP_TRIGGER,	 /* rpz-nsip */
+	RPZ_INVALID_TRIGGER, 	 /* dname does not contain valid trigger */
+};
+
+/**
+ * RPZ actions.
+ */
+enum rpz_action {
+	RPZ_NXDOMAIN_ACTION = 0,/* CNAME . */
+	RPZ_NODATA_ACTION,	/* CNAME *. */
+	RPZ_PASSTHRU_ACTION,	/* CNAME rpz-passthru. */
+	RPZ_DROP_ACTION,	/* CNAME rpz-drop. */
+	RPZ_TCP_ONLY_ACTION,	/* CNAME rpz-tcp-only. */
+	RPZ_INVALID_ACTION,	/* CNAME with (child of) TLD starting with
+				   "rpz-" in target, SOA, NS, DNAME and
+				   DNSSEC-related records. */
+	RPZ_LOCAL_DATA_ACTION,	/* anything else */
+	/* RPZ override actions */
+	RPZ_DISABLED_ACTION,    /* RPZ action disabled using override */
+	RPZ_NO_OVERRIDE_ACTION, /* RPZ action no override*/
+	RPZ_CNAME_OVERRIDE_ACTION, /* RPZ CNAME action override*/
+};
+
+/**
+ * RPZ containing policies. Pointed to from corresponding auth-zone. Part of a
+ * linked list to keep configuration order. Iterating or changing the linked
+ * list requires the rpz_lock from struct auth_zones.
+ */
+struct rpz {
+	struct local_zones* local_zones;
+	struct respip_set* respip_set;
+	uint8_t* taglist;
+	size_t taglistlen;
+	enum rpz_action action_override;
+	struct ub_packed_rrset_key* cname_override;
+	int log;
+	char* log_name;
+	struct rpz* next;
+	struct rpz* prev;
+	struct regional* region;
+};
+
+/**
+ * Create policy from RR and add to this RPZ.
+ * @param r: the rpz to add the policy to.
+ * @param aznamelen: the length of the auth-zone name
+ * @param dname: dname of the RR
+ * @param dnamelen: length of the dname
+ * @param rr_type: RR type of the RR
+ * @param rr_class: RR class of the RR
+ * @param rr_ttl: TTL of the RR
+ * @param rdatawl: rdata of the RR, prepended with the rdata size
+ * @param rdatalen: length if the RR, including the prepended rdata size
+ * @param rr: the complete RR, for logging purposes
+ * @param rr_len: the length of the complete RR
+ * @return: 0 on error
+ */
+int rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
+	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
+	uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len);
+
+/**
+ * Delete policy matching RR, used for IXFR.
+ * @param r: the rpz to add the policy to.
+ * @param aznamelen: the length of the auth-zone name
+ * @param dname: dname of the RR
+ * @param dnamelen: length of the dname
+ * @param rr_type: RR type of the RR
+ * @param rr_class: RR class of the RR
+ * @param rdatawl: rdata of the RR, prepended with the rdata size
+ * @param rdatalen: length if the RR, including the prepended rdata size
+ */
+void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
+	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
+	size_t rdatalen);
+
+/**
+ * Walk over the RPZ zones to find and apply a QNAME trigger policy.
+ * @param az: auth_zones struct, containing first RPZ item and RPZ lock
+ * @param env: module env
+ * @param qinfo: qinfo containing qname and qtype
+ * @param edns: edns data
+ * @param buf: buffer to write answer to
+ * @param temp: scratchpad
+ * @param repinfo: reply info
+ * @param taglist: taglist to lookup.
+ * @param taglen: lenth of taglist.
+ * @param stats: worker stats struct
+ * @return: 1 if client answer is ready, 0 to continue resolving
+ */
+int rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
+	struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
+	struct regional* temp, struct comm_reply* repinfo,
+	uint8_t* taglist, size_t taglen, struct ub_server_stats* stats);
+
+/**
+ * Delete RPZ
+ * @param r: RPZ struct to delete
+ */
+void rpz_delete(struct rpz* r);
+
+/**
+ * Clear local-zones and respip data in RPZ, used after reloading file or
+ * AXFR/HTTP transfer.
+ * @param r: RPZ to use
+ */
+int rpz_clear(struct rpz* r);
+
+/**
+ * Create RPZ. RPZ must be added to linked list after creation.
+ * @return: the newly created RPZ
+ */
+struct rpz* rpz_create(struct config_auth* p);
+
+/**
+ * String for RPZ action enum
+ * @param a: RPZ action to get string for
+ * @return: string for RPZ action
+ */
+const char* rpz_action_to_string(enum rpz_action a);
+
+enum rpz_action
+respip_action_to_rpz_action(enum respip_action a);
+
+/**
+ * Prepare RPZ after procesing feed content.
+ * @param r: RPZ to use
+ */
+void rpz_finish_config(struct rpz* r);
+
+/**
+ * Classify respip action for RPZ action
+ * @param a: RPZ action
+ * @return: the respip action
+ */
+enum respip_action
+rpz_action_to_respip_action(enum rpz_action a);
+
+#endif /* SERVICES_RPZ_H */
--- contrib/unbound/services/view.c.orig
+++ contrib/unbound/services/view.c
@@ -198,8 +198,6 @@
 						log_err("failed to insert "
 							"default zones into "
 							"local-zone list");
-						free(nd_str);
-						free(nd_type);
 						lock_rw_unlock(&v->lock);
 						return 0;
 					}
--- contrib/unbound/sldns/parse.c.orig
+++ contrib/unbound/sldns/parse.c
@@ -120,7 +120,7 @@
 			if (line_nr) {
 				*line_nr = *line_nr + 1;
 			}
-			if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
+			if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
 				*t = '\0';
 				return -1;
 			}
@@ -141,7 +141,8 @@
 		if (c != '\0' && c != '\n') {
 			i++;
 		}
-		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
+		/* is there space for the character and the zero after it */
+		if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
 			*t = '\0';
 			return -1;
 		}
@@ -325,8 +326,14 @@
 		if (c == '\n' && p != 0) {
 			/* in parentheses */
 			/* do not write ' ' if we want to skip spaces */
-			if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' '))))
+			if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) {
+				/* check for space for the space character and a zero delimiter after that. */
+				if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
+					*t = '\0';
+					return -1;
+				}
 				*t++ = ' ';
+			}
 			lc = c;
 			continue;
 		}
@@ -348,7 +355,7 @@
 		}
 
 		i++;
-		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
+		if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
 			*t = '\0';
 			return -1;
 		}
--- contrib/unbound/sldns/rrdef.c.orig
+++ contrib/unbound/sldns/rrdef.c
@@ -236,7 +236,7 @@
  */
 static sldns_rr_descriptor rdata_field_descriptors[] = {
 	/* 0 */
-	{ 0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	{(enum sldns_enum_rr_type)0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 	/* 1 */
 	{LDNS_RR_TYPE_A, "A", 1, 1, type_a_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 	/* 2 */
@@ -344,7 +344,7 @@
 	/* 53 */
 	{LDNS_RR_TYPE_SMIMEA, "SMIMEA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 	/* 54 */
-{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
         /* 55
 	 * Hip ends with 0 or more Rendezvous Servers represented as dname's.
 	 * Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field
@@ -358,8 +358,8 @@
 	/* 57 */
 	{LDNS_RR_TYPE_RKEY, "RKEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 #else
-{LDNS_RR_TYPE_NULL, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 #endif
 	/* 58 */
 	{LDNS_RR_TYPE_TALINK, "TALINK", 2, 2, type_talink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
@@ -372,54 +372,54 @@
 {LDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 	/* 62 */
 	{LDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 
 	/* 99 */
 	{LDNS_RR_TYPE_SPF,  "SPF", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
 
 	/* UINFO  [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 	/* UID    [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 	/* GID    [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 	/* UNSPEC [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 
 	/* 104 */
 	{LDNS_RR_TYPE_NID, "NID", 2, 2, type_nid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
@@ -435,145 +435,145 @@
 	/* 109 */
 	{LDNS_RR_TYPE_EUI64, "EUI64", 1, 1, type_eui64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 
-{LDNS_RR_TYPE_NULL, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 
 	/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
 	 * So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
@@ -605,7 +605,7 @@
 	/* 258 */
 	{LDNS_RR_TYPE_AVC, "AVC", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
 #else
-{LDNS_RR_TYPE_NULL, "TYPE258", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE258", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 #endif
 
 /* split in array, no longer contiguous */
@@ -614,7 +614,7 @@
 	/* 32768 */
 	{LDNS_RR_TYPE_TA, "TA", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 #else
-{LDNS_RR_TYPE_NULL, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{(enum sldns_enum_rr_type)0, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 #endif
 	/* 32769 */
 	{LDNS_RR_TYPE_DLV, "DLV", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }
@@ -710,18 +710,18 @@
 
 	/* special cases for query types */
 	if (strlen(name) == 4 && strncasecmp(name, "IXFR", 4) == 0) {
-		return 251;
+		return LDNS_RR_TYPE_IXFR;
 	} else if (strlen(name) == 4 && strncasecmp(name, "AXFR", 4) == 0) {
-		return 252;
+		return LDNS_RR_TYPE_AXFR;
 	} else if (strlen(name) == 5 && strncasecmp(name, "MAILB", 5) == 0) {
-		return 253;
+		return LDNS_RR_TYPE_MAILB;
 	} else if (strlen(name) == 5 && strncasecmp(name, "MAILA", 5) == 0) {
-		return 254;
+		return LDNS_RR_TYPE_MAILA;
 	} else if (strlen(name) == 3 && strncasecmp(name, "ANY", 3) == 0) {
-		return 255;
+		return LDNS_RR_TYPE_ANY;
 	}
 
-	return 0;
+	return (enum sldns_enum_rr_type)0;
 }
 
 sldns_rr_class
--- contrib/unbound/sldns/sbuffer.c.orig
+++ contrib/unbound/sldns/sbuffer.c
@@ -33,7 +33,6 @@
 	buffer->_position = 0;
 	buffer->_limit = buffer->_capacity = capacity;
 	buffer->_fixed = 0;
-	buffer->_vfixed = 0;
 	buffer->_status_err = 0;
 	
 	sldns_buffer_invariant(buffer);
@@ -49,7 +48,6 @@
 	buffer->_position = 0; 
 	buffer->_limit = buffer->_capacity = size;
 	buffer->_fixed = 0;
-	buffer->_vfixed = 0;
 	if (!buffer->_fixed && buffer->_data)
 		free(buffer->_data);
 	buffer->_data = malloc(size);
@@ -70,19 +68,8 @@
 	buffer->_data = data;
 	buffer->_capacity = buffer->_limit = size;
 	buffer->_fixed = 1;
-	buffer->_vfixed = 0;
 }
 
-void
-sldns_buffer_init_vfixed_frm_data(sldns_buffer *buffer, void *data, size_t size)
-{
-	memset(buffer, 0, sizeof(*buffer));
-	buffer->_data = data;
-	buffer->_capacity = buffer->_limit = size;
-	buffer->_fixed = 1;
-	buffer->_vfixed = 1;
-}
-
 int
 sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity)
 {
@@ -141,19 +128,6 @@
 		if (written == -1) {
 			buffer->_status_err = 1;
 			return -1;
-		} else if (!buffer->_vfixed && (size_t) written >= remaining) {
-			if (!sldns_buffer_reserve(buffer, (size_t) written + 1)) {
-				buffer->_status_err = 1;
-				return -1;
-			}
-			va_start(args, format);
-			written = vsnprintf((char *) sldns_buffer_current(buffer),
-			    sldns_buffer_remaining(buffer), format, args);
-			va_end(args);
-			if (written == -1) {
-				buffer->_status_err = 1;
-				return -1;
-			}
 		}
 		buffer->_position += written;
 	}
@@ -173,13 +147,6 @@
 	free(buffer);
 }
 
-void *
-sldns_buffer_export(sldns_buffer *buffer)
-{
-	buffer->_fixed = 1;
-	return buffer->_data;
-}
-
 void 
 sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from)
 {
--- contrib/unbound/sldns/sbuffer.h.orig
+++ contrib/unbound/sldns/sbuffer.h
@@ -130,17 +130,6 @@
 	/** If the buffer is fixed it cannot be resized */
 	unsigned _fixed : 1;
 
-	/** If the buffer is vfixed, no more than capacity bytes will be
-	 * written to _data, however the _position counter will be updated
-	 * with the amount that would have been written in consecutive
-	 * writes.  This allows for a modus operandi in which a sequence is
-	 * written on a fixed capacity buffer (perhaps with _data on stack).
-	 * When everything could be written, then the _data is immediately
-	 * usable, if not, then a buffer could be allocated sized precisely
-	 * to fit the data for a second attempt.
-	 */
-	unsigned _vfixed : 1;
-
 	/** The current state of the buffer. If writing to the buffer fails
 	 * for any reason, this value is changed. This way, you can perform
 	 * multiple writes in sequence and check for success afterwards. */
@@ -158,9 +147,9 @@
 sldns_buffer_invariant(sldns_buffer *buffer)
 {
 	assert(buffer != NULL);
-	assert(buffer->_position <= buffer->_limit || buffer->_vfixed);
+	assert(buffer->_position <= buffer->_limit);
 	assert(buffer->_limit <= buffer->_capacity);
-	assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0 && buffer->_limit == 0));
+	assert(buffer->_data != NULL);
 }
 #endif
 
@@ -193,19 +182,6 @@
 void sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size);
 
 /**
- * Setup a buffer with the data pointed to. No data copied, no memory allocs.
- * The buffer is "virtually" fixed.  Writes beyond size (the capacity) will
- * only update position, but no data will be written beyond capacity.  This
- * allows to determine how big the buffer should have been to contain all the
- * written data, by looking at the position with sldns_buffer_position(),
- * similarly to the return value of POSIX's snprintf.
- * \param[in] buffer pointer to the buffer to put the data in
- * \param[in] data the data to encapsulate in the buffer
- * \param[in] size the size of the data
- */
-void sldns_buffer_init_vfixed_frm_data(sldns_buffer *buffer, void *data, size_t size);
-
-/**
  * clears the buffer and make it ready for writing.  The buffer's limit
  * is set to the capacity and the position is set to 0.
  * \param[in] buffer the buffer to clear
@@ -268,7 +244,7 @@
 INLINE void
 sldns_buffer_set_position(sldns_buffer *buffer, size_t mark)
 {
-	assert(mark <= buffer->_limit || buffer->_vfixed);
+	assert(mark <= buffer->_limit);
 	buffer->_position = mark;
 }
 
@@ -282,7 +258,7 @@
 INLINE void
 sldns_buffer_skip(sldns_buffer *buffer, ssize_t count)
 {
-	assert(buffer->_position + count <= buffer->_limit || buffer->_vfixed);
+	assert(buffer->_position + count <= buffer->_limit);
 	buffer->_position += count;
 }
 
@@ -354,7 +330,7 @@
 INLINE uint8_t *
 sldns_buffer_at(const sldns_buffer *buffer, size_t at)
 {
-	assert(at <= buffer->_limit || buffer->_vfixed);
+	assert(at <= buffer->_limit);
 	return buffer->_data + at;
 }
 
@@ -404,7 +380,7 @@
 sldns_buffer_remaining_at(sldns_buffer *buffer, size_t at)
 {
 	sldns_buffer_invariant(buffer);
-	assert(at <= buffer->_limit || buffer->_vfixed);
+	assert(at <= buffer->_limit);
 	return at < buffer->_limit ? buffer->_limit - at : 0;
 }
 
@@ -457,15 +433,7 @@
 INLINE void
 sldns_buffer_write_at(sldns_buffer *buffer, size_t at, const void *data, size_t count)
 {
-	if (!buffer->_vfixed)
-		assert(sldns_buffer_available_at(buffer, at, count));
-	else if (sldns_buffer_remaining_at(buffer, at) == 0)
-		return;
-	else if (count > sldns_buffer_remaining_at(buffer, at)) {
-		memcpy(buffer->_data + at, data,
-		    sldns_buffer_remaining_at(buffer, at));
-		return;
-	}
+	assert(sldns_buffer_available_at(buffer, at, count));
 	memcpy(buffer->_data + at, data, count);
 }
 
@@ -480,15 +448,7 @@
 INLINE void
 sldns_buffer_set_at(sldns_buffer *buffer, size_t at, int c, size_t count)
 {
-    if (!buffer->_vfixed)
-        assert(sldns_buffer_available_at(buffer, at, count));
-    else if (sldns_buffer_remaining_at(buffer, at) == 0)
-        return;
-    else if (count > sldns_buffer_remaining_at(buffer, at)) {
-        memset(buffer->_data + at, c,
-            sldns_buffer_remaining_at(buffer, at));
-        return;
-    }
+	assert(sldns_buffer_available_at(buffer, at, count));
 	memset(buffer->_data + at, c, count);
 }
 
@@ -538,7 +498,6 @@
 INLINE void
 sldns_buffer_write_u8_at(sldns_buffer *buffer, size_t at, uint8_t data)
 {
-	if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
 	assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
 	buffer->_data[at] = data;
 }
@@ -564,7 +523,6 @@
 INLINE void
 sldns_buffer_write_u16_at(sldns_buffer *buffer, size_t at, uint16_t data)
 {
-	if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
 	assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
 	sldns_write_uint16(buffer->_data + at, data);
 }
@@ -590,7 +548,6 @@
 INLINE void
 sldns_buffer_write_u32_at(sldns_buffer *buffer, size_t at, uint32_t data)
 {
-	if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
 	assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
 	sldns_write_uint32(buffer->_data + at, data);
 }
@@ -604,7 +561,6 @@
 INLINE void
 sldns_buffer_write_u48_at(sldns_buffer *buffer, size_t at, uint64_t data)
 {
-	if (buffer->_vfixed && at + 6 > buffer->_limit) return;
 	assert(sldns_buffer_available_at(buffer, at, 6));
 	sldns_write_uint48(buffer->_data + at, data);
 }
@@ -781,14 +737,6 @@
 void sldns_buffer_free(sldns_buffer *buffer);
 
 /**
- * Makes the buffer fixed and returns a pointer to the data.  The
- * caller is responsible for free'ing the result.
- * \param[in] *buffer the buffer to be exported
- * \return void
- */
-void *sldns_buffer_export(sldns_buffer *buffer);
-
-/**
  * Copy contents of the from buffer to the result buffer and then flips 
  * the result buffer. Data will be silently truncated if the result buffer is
  * too small.
--- contrib/unbound/sldns/str2wire.c.orig
+++ contrib/unbound/sldns/str2wire.c
@@ -80,7 +80,7 @@
 	for (s = str; *s; s++, q++) {
 		if (q >= buf + *olen)
 			return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf);
-		if (q > buf + LDNS_MAX_DOMAINLEN)
+		if (q >= buf + LDNS_MAX_DOMAINLEN)
 			return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
 		switch (*s) {
 		case '.':
@@ -117,7 +117,7 @@
 		if(rel) *rel = 1;
 		if (q >= buf + *olen)
 			return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf);
-		if (q > buf + LDNS_MAX_DOMAINLEN) {
+		if (q >= buf + LDNS_MAX_DOMAINLEN) {
 			return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
 		}
                 if (label_len > LDNS_MAX_LABELLEN) {
@@ -150,6 +150,10 @@
 	if(s) return s;
 
 	if(rel && origin && dlen > 0) {
+		if((unsigned)dlen >= 0x00ffffffU ||
+			(unsigned)origin_len >= 0x00ffffffU)
+			/* guard against integer overflow in addition */
+			return RET_ERR(LDNS_WIREPARSE_ERR_GENERAL, *len);
 		if(dlen + origin_len - 1 > LDNS_MAX_DOMAINLEN)
 			return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW,
 				LDNS_MAX_DOMAINLEN);
@@ -168,7 +172,9 @@
 	uint8_t dname[LDNS_MAX_DOMAINLEN+1];
 	*len = sizeof(dname);
 	if(sldns_str2wire_dname_buf(str, dname, len) == 0) {
-		uint8_t* r = (uint8_t*)malloc(*len);
+		uint8_t* r;
+		if(*len > sizeof(dname)) return NULL;
+		r = (uint8_t*)malloc(*len);
 		if(r) return memcpy(r, dname, *len);
 	}
 	*len = 0;
@@ -187,7 +193,10 @@
 			sldns_buffer_position(strbuf));
 	}
 
-	if(strcmp(token, "@") == 0) {
+	if(token_len < 2) /* make sure there is space to read "@" or "" */
+		return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
+			sldns_buffer_position(strbuf));
+	if(token[0]=='@' && token[1]=='\0') {
 		uint8_t* tocopy;
 		if (origin) {
 			*dname_len = origin_len;
@@ -1094,7 +1103,7 @@
 	while(sldns_parse_char(&ch, &s)) {
 		if(sl >= 255)
 			return RET_ERR(LDNS_WIREPARSE_ERR_INVALID_STR, s-str);
-		if(*len < sl+1)
+		if(*len < sl+2)
 			return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
 				s-str);
 		rd[++sl] = ch;
@@ -2095,6 +2104,8 @@
 	char* s;
 	int n;
 	n = strtol(str, &s, 10);
+	if(n < 0) /* negative number not allowed */
+		return LDNS_WIREPARSE_ERR_SYNTAX;
 	if(*len < ((size_t)n)+2)
 		return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
 	if(n > 65535)
--- contrib/unbound/sldns/wire2str.c.orig
+++ contrib/unbound/sldns/wire2str.c
@@ -22,6 +22,7 @@
 #include "sldns/parseutil.h"
 #include "sldns/sbuffer.h"
 #include "sldns/keyraw.h"
+#include "util/data/dname.h"
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
@@ -252,13 +253,13 @@
 int sldns_wire2str_rr_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
 {
 	/* use arguments as temporary variables */
-	return sldns_wire2str_rr_scan(&d, &dlen, &s, &slen, NULL, 0);
+	return sldns_wire2str_rr_scan(&d, &dlen, &s, &slen, NULL, 0, NULL);
 }
 
 int sldns_wire2str_rrquestion_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
 {
 	/* use arguments as temporary variables */
-	return sldns_wire2str_rrquestion_scan(&d, &dlen, &s, &slen, NULL, 0);
+	return sldns_wire2str_rrquestion_scan(&d, &dlen, &s, &slen, NULL, 0, NULL);
 }
 
 int sldns_wire2str_rdata_buf(uint8_t* rdata, size_t rdata_len, char* str,
@@ -266,13 +267,13 @@
 {
 	/* use arguments as temporary variables */
 	return sldns_wire2str_rdata_scan(&rdata, &rdata_len, &str, &str_len,
-		rrtype, NULL, 0);
+		rrtype, NULL, 0, NULL);
 }
 
 int sldns_wire2str_rr_unknown_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
 {
 	/* use arguments as temporary variables */
-	return sldns_wire2str_rr_unknown_scan(&d, &dlen, &s, &slen, NULL, 0);
+	return sldns_wire2str_rr_unknown_scan(&d, &dlen, &s, &slen, NULL, 0, NULL);
 }
 
 int sldns_wire2str_rr_comment_buf(uint8_t* rr, size_t rrlen, size_t dname_len,
@@ -310,7 +311,7 @@
 int sldns_wire2str_dname_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
 {
 	/* use arguments as temporary variables */
-	return sldns_wire2str_dname_scan(&d, &dlen, &s, &slen, NULL, 0);
+	return sldns_wire2str_dname_scan(&d, &dlen, &s, &slen, NULL, 0, NULL);
 }
 
 int sldns_str_vprint(char** str, size_t* slen, const char* format, va_list args)
@@ -365,7 +366,7 @@
 
 int sldns_wire2str_pkt_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
 {
-	int w = 0;
+	int w = 0, comprloop = 0;
 	unsigned qdcount, ancount, nscount, arcount, i;
 	uint8_t* pkt = *d;
 	size_t pktlen = *dlen;
@@ -382,25 +383,25 @@
 	w += sldns_str_print(s, slen, ";; QUESTION SECTION:\n");
 	for(i=0; i<qdcount; i++) {
 		w += sldns_wire2str_rrquestion_scan(d, dlen, s, slen,
-			pkt, pktlen);
+			pkt, pktlen, &comprloop);
 		if(!*dlen) break;
 	}
 	w += sldns_str_print(s, slen, "\n");
 	w += sldns_str_print(s, slen, ";; ANSWER SECTION:\n");
 	for(i=0; i<ancount; i++) {
-		w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen);
+		w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop);
 		if(!*dlen) break;
 	}
 	w += sldns_str_print(s, slen, "\n");
 	w += sldns_str_print(s, slen, ";; AUTHORITY SECTION:\n");
 	for(i=0; i<nscount; i++) {
-		w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen);
+		w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop);
 		if(!*dlen) break;
 	}
 	w += sldns_str_print(s, slen, "\n");
 	w += sldns_str_print(s, slen, ";; ADDITIONAL SECTION:\n");
 	for(i=0; i<arcount; i++) {
-		w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen);
+		w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop);
 		if(!*dlen) break;
 	}
 	/* other fields: WHEN(time), SERVER(IP) not available here. */
@@ -449,7 +450,7 @@
 }
 
 int sldns_wire2str_rr_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
-	uint8_t* pkt, size_t pktlen)
+	uint8_t* pkt, size_t pktlen, int* comprloop)
 {
 	int w = 0;
 	uint8_t* rr = *d;
@@ -464,7 +465,7 @@
 
 	/* try to scan the rdata with pretty-printing, but if that fails, then
 	 * scan the rdata as an unknown RR type */
-	w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen);
+	w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop);
 	w += sldns_str_print(s, slen, "\t");
 	dname_off = rrlen-(*dlen);
 	if(*dlen == 4) {
@@ -508,7 +509,8 @@
 		w += print_remainder_hex(";Error partial rdata 0x", d, dlen, s, slen);
 		return w + sldns_str_print(s, slen, "\n");
 	}
-	w += sldns_wire2str_rdata_scan(d, &rdlen, s, slen, rrtype, pkt, pktlen);
+	w += sldns_wire2str_rdata_scan(d, &rdlen, s, slen, rrtype, pkt, pktlen,
+		comprloop);
 	(*dlen) -= (ordlen-rdlen);
 
 	/* default comment */
@@ -519,11 +521,11 @@
 }
 
 int sldns_wire2str_rrquestion_scan(uint8_t** d, size_t* dlen, char** s,
-	size_t* slen, uint8_t* pkt, size_t pktlen)
+	size_t* slen, uint8_t* pkt, size_t pktlen, int* comprloop)
 {
 	int w = 0;
 	uint16_t t, c;
-	w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen);
+	w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop);
 	w += sldns_str_print(s, slen, "\t");
 	if(*dlen < 4) {
 		if(*dlen == 0)
@@ -543,11 +545,11 @@
 }
 
 int sldns_wire2str_rr_unknown_scan(uint8_t** d, size_t* dlen, char** s,
-	size_t* slen, uint8_t* pkt, size_t pktlen)
+	size_t* slen, uint8_t* pkt, size_t pktlen, int* comprloop)
 {
 	size_t rdlen, ordlen;
 	int w = 0;
-	w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen);
+	w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop);
 	w += sldns_str_print(s, slen, "\t");
 	w += sldns_rr_tcttl_scan(d, dlen, s, slen);
 	w += sldns_str_print(s, slen, "\t");
@@ -585,6 +587,7 @@
 	if(rrlen < dname_off + 10) return 0;
 	rdlen = sldns_read_uint16(rr+dname_off+8);
 	if(rrlen < dname_off + 10 + rdlen) return 0;
+	if(rdlen < 2) return 0;
 	rdata = rr + dname_off + 10;
 	flags = (int)sldns_read_uint16(rdata);
 	w += sldns_str_print(s, slen, " ;{");
@@ -698,7 +701,8 @@
 }
 
 int sldns_wire2str_rdata_scan(uint8_t** d, size_t* dlen, char** s,
-	size_t* slen, uint16_t rrtype, uint8_t* pkt, size_t pktlen)
+	size_t* slen, uint16_t rrtype, uint8_t* pkt, size_t pktlen,
+	int* comprloop)
 {
 	/* try to prettyprint, but if that fails, use unknown format */
 	uint8_t* origd = *d;
@@ -724,7 +728,7 @@
 		if(r_cnt != 0)
 			w += sldns_str_print(s, slen, " ");
 		n = sldns_wire2str_rdf_scan(d, dlen, s, slen, rdftype,
-			pkt, pktlen);
+			pkt, pktlen, comprloop);
 		if(n == -1) {
 		failed:
 			/* failed, use unknown format */
@@ -775,14 +779,20 @@
 }
 
 int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
-	uint8_t* pkt, size_t pktlen)
+	uint8_t* pkt, size_t pktlen, int* comprloop)
 {
 	int w = 0;
 	/* spool labels onto the string, use compression if its there */
 	uint8_t* pos = *d;
 	unsigned i, counter=0;
-	const unsigned maxcompr = 1000; /* loop detection, max compr ptrs */
+	unsigned maxcompr = MAX_COMPRESS_PTRS; /* loop detection, max compr ptrs */
 	int in_buf = 1;
+	if(comprloop) {
+		if(*comprloop != 0)
+			maxcompr = 30; /* for like ipv6 reverse name, per label */
+		if(*comprloop > 4)
+			maxcompr = 4; /* just don't want to spend time, any more */
+	}
 	if(*dlen == 0) return sldns_str_print(s, slen, "ErrorMissingDname");
 	if(*pos == 0) {
 		(*d)++;
@@ -789,7 +799,7 @@
 		(*dlen)--;
 		return sldns_str_print(s, slen, ".");
 	}
-	while(*pos) {
+	while((!pkt || pos < pkt+pktlen) && *pos) {
 		/* read label length */
 		uint8_t labellen = *pos++;
 		if(in_buf) { (*d)++; (*dlen)--; }
@@ -810,9 +820,12 @@
 			if(!pkt || target >= pktlen)
 				return w + sldns_str_print(s, slen,
 					"ErrorComprPtrOutOfBounds");
-			if(counter++ > maxcompr)
+			if(counter++ > maxcompr) {
+				if(comprloop && *comprloop < 10)
+					(*comprloop)++;
 				return w + sldns_str_print(s, slen,
 					"ErrorComprPtrLooped");
+			}
 			in_buf = 0;
 			pos = pkt+target;
 			continue;
@@ -928,7 +941,7 @@
 }
 
 int sldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
-	int rdftype, uint8_t* pkt, size_t pktlen)
+	int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop)
 {
 	if(*dlen == 0) return 0;
 	switch(rdftype) {
@@ -935,7 +948,7 @@
 	case LDNS_RDF_TYPE_NONE:
 		return 0;
 	case LDNS_RDF_TYPE_DNAME:
-		return sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen);
+		return sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop);
 	case LDNS_RDF_TYPE_INT8:
 		return sldns_wire2str_int8_scan(d, dlen, s, slen);
 	case LDNS_RDF_TYPE_INT16:
@@ -987,7 +1000,7 @@
 		return sldns_wire2str_atma_scan(d, dlen, s, slen);
 	case LDNS_RDF_TYPE_IPSECKEY:
 		return sldns_wire2str_ipseckey_scan(d, dlen, s, slen, pkt,
-			pktlen);
+			pktlen, comprloop);
 	case LDNS_RDF_TYPE_HIP:
 		return sldns_wire2str_hip_scan(d, dlen, s, slen);
 	case LDNS_RDF_TYPE_INT16_DATA:
@@ -1529,7 +1542,7 @@
 
 /* internal scan routine that can modify arguments on failure */
 static int sldns_wire2str_ipseckey_scan_internal(uint8_t** d, size_t* dl,
-	char** s, size_t* sl, uint8_t* pkt, size_t pktlen)
+	char** s, size_t* sl, uint8_t* pkt, size_t pktlen, int* comprloop)
 {
 	/* http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt*/
 	uint8_t precedence, gateway_type, algorithm;
@@ -1557,7 +1570,7 @@
 		w += sldns_wire2str_aaaa_scan(d, dl, s, sl);
 		break;
 	case 3: /* dname */
-		w += sldns_wire2str_dname_scan(d, dl, s, sl, pkt, pktlen);
+		w += sldns_wire2str_dname_scan(d, dl, s, sl, pkt, pktlen, comprloop);
 		break;
 	default: /* unknown */
 		return -1;
@@ -1571,12 +1584,12 @@
 }
 
 int sldns_wire2str_ipseckey_scan(uint8_t** d, size_t* dl, char** s, size_t* sl,
-	uint8_t* pkt, size_t pktlen)
+	uint8_t* pkt, size_t pktlen, int* comprloop)
 {
 	uint8_t* od = *d;
 	char* os = *s;
 	size_t odl = *dl, osl = *sl;
-	int w=sldns_wire2str_ipseckey_scan_internal(d, dl, s, sl, pkt, pktlen);
+	int w=sldns_wire2str_ipseckey_scan_internal(d, dl, s, sl, pkt, pktlen, comprloop);
 	if(w == -1) {
 		*d = od;
 		*s = os;
@@ -1908,8 +1921,8 @@
 	return w;
 }
 
-static int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl, uint8_t* data,
-	size_t len)
+static int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl,
+	uint8_t* data, size_t len)
 {
 	int w = 0;
 	uint16_t timeout;
--- contrib/unbound/sldns/wire2str.h.orig
+++ contrib/unbound/sldns/wire2str.h
@@ -156,10 +156,11 @@
  * @param str_len: length of string buffer.
  * @param pkt: packet for decompression, if NULL no decompression.
  * @param pktlen: length of packet buffer.
+ * @param comprloop: if pkt, bool detects compression loops.
  * @return number of characters (except null) needed to print.
  */
 int sldns_wire2str_rr_scan(uint8_t** data, size_t* data_len, char** str,
-	size_t* str_len, uint8_t* pkt, size_t pktlen);
+	size_t* str_len, uint8_t* pkt, size_t pktlen, int* comprloop);
 
 /**
  * Scan wireformat question rr to string, with user buffers.
@@ -170,10 +171,11 @@
  * @param str_len: length of string buffer.
  * @param pkt: packet for decompression, if NULL no decompression.
  * @param pktlen: length of packet buffer.
+ * @param comprloop: if pkt, bool detects compression loops.
  * @return number of characters (except null) needed to print.
  */
 int sldns_wire2str_rrquestion_scan(uint8_t** data, size_t* data_len, char** str,
-	size_t* str_len, uint8_t* pkt, size_t pktlen);
+	size_t* str_len, uint8_t* pkt, size_t pktlen, int* comprloop);
 
 /**
  * Scan wireformat RR to string in unknown RR format, with user buffers.
@@ -184,10 +186,11 @@
  * @param str_len: length of string buffer.
  * @param pkt: packet for decompression, if NULL no decompression.
  * @param pktlen: length of packet buffer.
+ * @param comprloop: if pkt, bool detects compression loops.
  * @return number of characters (except null) needed to print.
  */
 int sldns_wire2str_rr_unknown_scan(uint8_t** data, size_t* data_len, char** str,
-	size_t* str_len, uint8_t* pkt, size_t pktlen);
+	size_t* str_len, uint8_t* pkt, size_t pktlen, int* comprloop);
 
 /**
  * Print to string the RR-information comment in default format,
@@ -228,10 +231,12 @@
  * @param rrtype: RR type of Rdata, host format.
  * @param pkt: packet for decompression, if NULL no decompression.
  * @param pktlen: length of packet buffer.
+ * @param comprloop: if pkt, bool detects compression loops.
  * @return number of characters (except null) needed to print.
  */
 int sldns_wire2str_rdata_scan(uint8_t** data, size_t* data_len, char** str,
-	size_t* str_len, uint16_t rrtype, uint8_t* pkt, size_t pktlen);
+	size_t* str_len, uint16_t rrtype, uint8_t* pkt, size_t pktlen,
+	int* comprloop);
 
 /**
  * Scan wireformat rdata to string in unknown format, with user buffers.
@@ -254,10 +259,17 @@
  * @param str_len: length of string buffer.
  * @param pkt: packet for decompression, if NULL no decompression.
  * @param pktlen: length of packet buffer.
+ * @param comprloop: inout bool, that is set true if compression loop failure
+ * 	happens.  Pass in 0, if passsed in as true, a lower bound is set
+ * 	on compression loops to stop arbitrary long packet parse times.
+ * 	This is meant so you can set it to 0 at the start of a list of dnames,
+ * 	and then scan all of them in sequence, if a loop happens, it becomes
+ * 	true and then it becomes more strict for the next dnames in the list.
+ * 	You can leave it at NULL if there is no pkt (pkt is NULL too).
  * @return number of characters (except null) needed to print.
  */
 int sldns_wire2str_dname_scan(uint8_t** data, size_t* data_len, char** str,
-	size_t* str_len, uint8_t* pkt, size_t pktlen);
+	size_t* str_len, uint8_t* pkt, size_t pktlen, int* comprloop);
 
 /**
  * Scan wireformat rr type to string, with user buffers.
@@ -492,11 +504,13 @@
  * @param rdftype: the type of the rdata field, enum sldns_rdf_type.
  * @param pkt: packet for decompression, if NULL no decompression.
  * @param pktlen: length of packet buffer.
+ * @param comprloop: if pkt, bool detects compression loops.
  * @return number of characters (except null) needed to print.
  * 	Can return -1 on failure.
  */
 int sldns_wire2str_rdf_scan(uint8_t** data, size_t* data_len, char** str,
-	size_t* str_len, int rdftype, uint8_t* pkt, size_t pktlen);
+	size_t* str_len, int rdftype, uint8_t* pkt, size_t pktlen,
+	int* comprloop);
 
 /**
  * Scan wireformat int8 field to string, with user buffers.
@@ -793,11 +807,12 @@
  * @param str_len: length of string buffer.
  * @param pkt: packet for decompression, if NULL no decompression.
  * @param pktlen: length of packet buffer.
+ * @param comprloop: if pkt, bool detects compression loops.
  * @return number of characters (except null) needed to print.
  * 	Can return -1 on failure.
  */
 int sldns_wire2str_ipseckey_scan(uint8_t** data, size_t* data_len, char** str,
-	size_t* str_len, uint8_t* pkt, size_t pktlen);
+	size_t* str_len, uint8_t* pkt, size_t pktlen, int* comprloop);
 
 /**
  * Scan wireformat HIP (algo, HIT, pubkey) field to string, with user buffers.
--- contrib/unbound/smallapp/unbound-anchor.c.orig
+++ contrib/unbound/smallapp/unbound-anchor.c
@@ -190,6 +190,7 @@
 	printf("-x path		pathname to xml in url, default %s\n", XMLNAME);
 	printf("-s path		pathname to p7s in url, default %s\n", P7SNAME);
 	printf("-n name		signer's subject emailAddress, default %s\n", P7SIGNER);
+	printf("-b address	source address to bind to\n");
 	printf("-4		work using IPv4 only\n");
 	printf("-6		work using IPv6 only\n");
 	printf("-f resolv.conf	use given resolv.conf\n");
@@ -277,7 +278,7 @@
  */
 static struct ub_ctx* 
 create_unbound_context(const char* res_conf, const char* root_hints,
-	const char* debugconf, int ip4only, int ip6only)
+	const char* debugconf, const char* srcaddr, int ip4only, int ip6only)
 {
 	int r;
 	struct ub_ctx* ctx = ub_ctx_create();
@@ -301,6 +302,10 @@
 		r = ub_ctx_set_option(ctx, "root-hints:", root_hints);
 		if(r) ub_ctx_error_exit(ctx, root_hints, ub_strerror(r));
 	}
+	if(srcaddr) {
+		r = ub_ctx_set_option(ctx, "outgoing-interface:", srcaddr);
+		if(r) ub_ctx_error_exit(ctx, srcaddr, ub_strerror(r));
+	}
 	if(ip4only) {
 		r = ub_ctx_set_option(ctx, "do-ip6:", "no");
 		if(r) ub_ctx_error_exit(ctx, "ip4only", ub_strerror(r));
@@ -350,7 +355,7 @@
 		exit(0);
 	}
 	while(!BIO_eof(bio)) {
-		X509* x = PEM_read_bio_X509(bio, NULL, 0, NULL);
+		X509* x = PEM_read_bio_X509(bio, NULL, NULL, NULL);
 		if(x == NULL) {
 			if(verb) {
 				printf("failed to read X509\n");
@@ -391,7 +396,7 @@
 		return NULL;
 	}
 	while(!feof(in)) {
-		X509* x = PEM_read_X509(in, NULL, 0, NULL);
+		X509* x = PEM_read_X509(in, NULL, NULL, NULL);
 		if(x == NULL) {
 			if(verb) {
 				printf("failed to read X509 file\n");
@@ -613,6 +618,7 @@
  * @param res_conf: resolv.conf (if any).
  * @param root_hints: root hints (if any).
  * @param debugconf: unbound.conf for debugging options.
+ * @param srcaddr: source address option (if any).
  * @param ip4only: use only ip4 for resolve and only lookup A
  * @param ip6only: use only ip6 for resolve and only lookup AAAA
  * 	default is to lookup A and AAAA using ip4 and ip6.
@@ -620,7 +626,8 @@
  */
 static struct ip_list*
 resolve_name(const char* host, int port, const char* res_conf,
-	const char* root_hints, const char* debugconf, int ip4only, int ip6only)
+	const char* root_hints, const char* debugconf,
+	const char* srcaddr, int ip4only, int ip6only)
 {
 	struct ub_ctx* ctx;
 	struct ip_list* list = NULL;
@@ -631,7 +638,7 @@
 	
 	/* create resolver context */
 	ctx = create_unbound_context(res_conf, root_hints, debugconf,
-        	ip4only, ip6only);
+        	srcaddr, ip4only, ip6only);
 
 	/* try resolution of A */
 	if(!ip6only) {
@@ -721,7 +728,7 @@
 
 /** connect to IP address */
 static int
-connect_to_ip(struct ip_list* ip)
+connect_to_ip(struct ip_list* ip, struct ip_list* src)
 {
 	int fd;
 	verb_addr("connect to", ip);
@@ -731,6 +738,11 @@
 		print_sock_err("socket");
 		return -1;
 	}
+	if(src && bind(fd, (struct sockaddr*)&src->addr, src->len) < 0) {
+		print_sock_err("bind");
+		fd_close(fd);
+		return -1;
+	}
 	if(connect(fd, (struct sockaddr*)&ip->addr, ip->len) < 0) {
 		print_sock_err("connect");
 		fd_close(fd);
@@ -763,7 +775,7 @@
 		return NULL;
 	}
 	SSL_set_connect_state(ssl);
-	(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+	(void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY);
 	if(!SSL_set_fd(ssl, fd)) {
 		if(verb) printf("SSL_set_fd error\n");
 		SSL_free(ssl);
@@ -924,7 +936,7 @@
 	size_t got = 0;
 	int r;
 	char* data;
-	if(len >= 0xfffffff0)
+	if((unsigned)len >= (unsigned)0xfffffff0)
 		return NULL; /* to protect against integer overflow in malloc*/
 	data = malloc(len+1);
 	if(!data) {
@@ -1103,7 +1115,8 @@
 
 /** https to an IP addr, return BIO with pathname or NULL */
 static BIO*
-https_to_ip(struct ip_list* ip, const char* pathname, const char* urlname)
+https_to_ip(struct ip_list* ip, const char* pathname, const char* urlname,
+	struct ip_list* src)
 {
 	int fd;
 	SSL* ssl;
@@ -1112,7 +1125,7 @@
 	if(!sslctx) {
 		return NULL;
 	}
-	fd = connect_to_ip(ip);
+	fd = connect_to_ip(ip, src);
 	if(fd == -1) {
 		SSL_CTX_free(sslctx);
 		return NULL;
@@ -1140,10 +1153,12 @@
  * @param ip_list: list of IP addresses to use to fetch from.
  * @param pathname: pathname of file on server to GET.
  * @param urlname: name to pass as the virtual host for this request.
+ * @param src: if nonNULL, source address to bind to.
  * @return a memory BIO with the file in it.
  */
 static BIO*
-https(struct ip_list* ip_list, const char* pathname, const char* urlname)
+https(struct ip_list* ip_list, const char* pathname, const char* urlname,
+	struct ip_list* src)
 {
 	struct ip_list* ip;
 	BIO* bio = NULL;
@@ -1151,7 +1166,7 @@
 	wipe_ip_usage(ip_list);
 	while( (ip = pick_random_ip(ip_list)) ) {
 		ip->used = 1;
-		bio = https_to_ip(ip, pathname, urlname);
+		bio = https_to_ip(ip, pathname, urlname, src);
 		if(bio) break;
 	}
 	if(!bio) {
@@ -1906,11 +1921,14 @@
 do_certupdate(const char* root_anchor_file, const char* root_cert_file,
 	const char* urlname, const char* xmlname, const char* p7sname,
 	const char* p7signer, const char* res_conf, const char* root_hints,
-	const char* debugconf, int ip4only, int ip6only, int port)
+	const char* debugconf, const char* srcaddr, int ip4only, int ip6only,
+	int port)
+
 {
 	STACK_OF(X509)* cert;
 	BIO *xml, *p7s;
 	struct ip_list* ip_list = NULL;
+	struct ip_list* src = NULL;
 
 	/* read pem file or provide builtin */
 	cert = read_cert_or_builtin(root_cert_file);
@@ -1917,8 +1935,13 @@
 
 	/* lookup A, AAAA for the urlname (or parse urlname if IP address) */
 	ip_list = resolve_name(urlname, port, res_conf, root_hints, debugconf,
-		ip4only, ip6only);
+	        srcaddr, ip4only, ip6only);
 
+	if(srcaddr && !(src = parse_ip_addr(srcaddr, 0))) {
+		if(verb) printf("cannot parse source address: %s\n", srcaddr);
+		exit(0);
+	}
+
 #ifdef USE_WINSOCK
 	if(1) { /* libunbound finished, startup WSA for the https connection */
 		WSADATA wsa_data;
@@ -1933,8 +1956,8 @@
 #endif
 
 	/* fetch the necessary files over HTTPS */
-	xml = https(ip_list, xmlname, urlname);
-	p7s = https(ip_list, p7sname, urlname);
+	xml = https(ip_list, xmlname, urlname, src);
+	p7s = https(ip_list, p7sname, urlname, src);
 
 	/* verify and update the root anchor */
 	verify_and_update_anchor(root_anchor_file, xml, p7s, cert, p7signer);
@@ -2185,7 +2208,7 @@
 
 static struct ub_result *
 fetch_root_key(const char* root_anchor_file, const char* res_conf,
-	const char* root_hints, const char* debugconf,
+	const char* root_hints, const char* debugconf, const char* srcaddr,
 	int ip4only, int ip6only)
 {
 	struct ub_ctx* ctx;
@@ -2192,7 +2215,7 @@
 	struct ub_result* dnskey;
 
 	ctx = create_unbound_context(res_conf, root_hints, debugconf,
-		ip4only, ip6only);
+		srcaddr, ip4only, ip6only);
 	add_5011_probe_root(ctx, root_anchor_file);
 	dnskey = prime_root_key(ctx);
 	ub_ctx_delete(ctx);
@@ -2204,8 +2227,8 @@
 do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
 	const char* urlname, const char* xmlname, const char* p7sname,
 	const char* p7signer, const char* res_conf, const char* root_hints,
-	const char* debugconf, int ip4only, int ip6only, int force,
-	int res_conf_fallback, int port)
+	const char* debugconf, const char* srcaddr, int ip4only, int ip6only, 
+	int force, int res_conf_fallback, int port)
 {
 	struct ub_result* dnskey;
 	int used_builtin = 0;
@@ -2219,7 +2242,7 @@
 	/* make unbound context with 5011-probe for root anchor,
 	 * and probe . DNSKEY */
 	dnskey = fetch_root_key(root_anchor_file, res_conf,
-		root_hints, debugconf, ip4only, ip6only);
+		root_hints, debugconf, srcaddr, ip4only, ip6only);
 	rcode = dnskey->rcode;
 
 	if (res_conf_fallback && res_conf && !dnskey->secure) {
@@ -2227,7 +2250,7 @@
 		ub_resolve_free(dnskey);
 		/* try direct query without res_conf */
 		dnskey = fetch_root_key(root_anchor_file, NULL,
-			root_hints, debugconf, ip4only, ip6only);
+			root_hints, debugconf, srcaddr, ip4only, ip6only);
 		if (rcode != 0 && dnskey->rcode == 0) {
 			res_conf = NULL;
 			rcode = 0;
@@ -2248,7 +2271,7 @@
 		probe_date_allows_certupdate(root_anchor_file)) || force) {
 		if(do_certupdate(root_anchor_file, root_cert_file, urlname,
 			xmlname, p7sname, p7signer, res_conf, root_hints,
-			debugconf, ip4only, ip6only, port))
+			debugconf, srcaddr, ip4only, ip6only, port))
 			return 1;
 		return used_builtin;
 	}
@@ -2274,10 +2297,11 @@
 	const char* res_conf = NULL;
 	const char* root_hints = NULL;
 	const char* debugconf = NULL;
+	const char* srcaddr = NULL;
 	int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT;
 	int res_conf_fallback = 0;
 	/* parse the options */
-	while( (c=getopt(argc, argv, "46C:FRP:a:c:f:hln:r:s:u:vx:")) != -1) {
+	while( (c=getopt(argc, argv, "46C:FRP:a:b:c:f:hln:r:s:u:vx:")) != -1) {
 		switch(c) {
 		case 'l':
 			dolist = 1;
@@ -2291,6 +2315,9 @@
 		case 'a':
 			root_anchor_file = optarg;
 			break;
+		case 'b':
+			srcaddr = optarg;
+			break;
 		case 'c':
 			root_cert_file = optarg;
 			break;
@@ -2345,7 +2372,9 @@
 	ERR_load_SSL_strings();
 #endif
 #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
+#  ifndef S_SPLINT_S
 	OpenSSL_add_all_algorithms();
+#  endif
 #else
 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
 		| OPENSSL_INIT_ADD_ALL_DIGESTS
@@ -2361,5 +2390,5 @@
 
 	return do_root_update_work(root_anchor_file, root_cert_file, urlname,
 		xmlname, p7sname, p7signer, res_conf, root_hints, debugconf,
-		ip4only, ip6only, force, res_conf_fallback, port);
+		srcaddr, ip4only, ip6only, force, res_conf_fallback, port);
 }
--- contrib/unbound/smallapp/unbound-checkconf.c.orig
+++ contrib/unbound/smallapp/unbound-checkconf.c
@@ -146,6 +146,42 @@
 	edns_known_options_delete(&env);
 }
 
+/** true if addr is a localhost address, 127.0.0.1 or ::1 (with maybe "@port"
+ * after it) */
+static int
+str_addr_is_localhost(const char* a)
+{
+	if(strncmp(a, "127.", 4) == 0) return 1;
+	if(strncmp(a, "::1", 3) == 0) return 1;
+	return 0;
+}
+
+/** check do-not-query-localhost */
+static void
+donotquerylocalhostcheck(struct config_file* cfg)
+{
+	if(cfg->donotquery_localhost) {
+		struct config_stub* p;
+		struct config_strlist* s;
+		for(p=cfg->forwards; p; p=p->next) {
+			for(s=p->addrs; s; s=s->next) {
+				if(str_addr_is_localhost(s->str)) {
+					fprintf(stderr, "unbound-checkconf: warning: forward-addr: '%s' is specified for forward-zone: '%s', but do-not-query-localhost: yes means that the address will not be used for lookups.\n",
+						s->str, p->name);
+				}
+			}
+		}
+		for(p=cfg->stubs; p; p=p->next) {
+			for(s=p->addrs; s; s=s->next) {
+				if(str_addr_is_localhost(s->str)) {
+					fprintf(stderr, "unbound-checkconf: warning: stub-addr: '%s' is specified for stub-zone: '%s', but do-not-query-localhost: yes means that the address will not be used for lookups.\n",
+						s->str, p->name);
+				}
+			}
+		}
+	}
+}
+
 /** check localzones */
 static void
 localzonechecks(struct config_file* cfg)
@@ -431,7 +467,7 @@
 
 /** check configuration for errors */
 static void
-morechecks(struct config_file* cfg, const char* fname)
+morechecks(struct config_file* cfg)
 {
 	warn_hosts("stub-host", cfg->stubs);
 	warn_hosts("forward-host", cfg->forwards);
@@ -463,19 +499,6 @@
 		!is_dir(cfg->chrootdir)) {
 		fatal_exit("bad chroot directory");
 	}
-	if(cfg->chrootdir && cfg->chrootdir[0]) {
-		char buf[10240];
-		buf[0] = 0;
-		if(fname[0] != '/') {
-			if(getcwd(buf, sizeof(buf)) == NULL)
-				fatal_exit("getcwd: %s", strerror(errno));
-			(void)strlcat(buf, "/", sizeof(buf));
-		}
-		(void)strlcat(buf, fname, sizeof(buf));
-		if(strncmp(buf, cfg->chrootdir, strlen(cfg->chrootdir)) != 0)
-			fatal_exit("config file %s is not inside chroot %s",
-				buf, cfg->chrootdir);
-	}
 	if(cfg->directory && cfg->directory[0]) {
 		char* ad = fname_after_chroot(cfg->directory, cfg, 0);
 		if(!ad) fatal_exit("out of memory");
@@ -525,10 +548,7 @@
 	/* check that the modules listed in module_conf exist */
 	check_modules_exist(cfg->module_conf);
 
-	/* There should be no reason for 'respip' module not to work with
-	 * dns64, but it's not explicitly confirmed,  so the combination is
-	 * excluded below.   It's simply unknown yet for the combination of
-	 * respip and other modules. */
+	/* Respip is known to *not* work with dns64. */
 	if(strcmp(cfg->module_conf, "iterator") != 0
 		&& strcmp(cfg->module_conf, "validator iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
@@ -537,7 +557,9 @@
 		&& strcmp(cfg->module_conf, "respip validator iterator") != 0
 #ifdef WITH_PYTHONMODULE
 		&& strcmp(cfg->module_conf, "python iterator") != 0
+		&& strcmp(cfg->module_conf, "python respip iterator") != 0
 		&& strcmp(cfg->module_conf, "python validator iterator") != 0
+		&& strcmp(cfg->module_conf, "python respip validator iterator") != 0
 		&& strcmp(cfg->module_conf, "validator python iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 python iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 python validator iterator") != 0
@@ -547,7 +569,9 @@
 #endif
 #ifdef USE_CACHEDB
 		&& strcmp(cfg->module_conf, "validator cachedb iterator") != 0
+		&& strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0
 		&& strcmp(cfg->module_conf, "cachedb iterator") != 0
+		&& strcmp(cfg->module_conf, "respip cachedb iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0
 #endif
@@ -557,36 +581,62 @@
 		&& strcmp(cfg->module_conf, "dns64 python cachedb iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 python validator cachedb iterator") != 0
 		&& strcmp(cfg->module_conf, "python cachedb iterator") != 0
+		&& strcmp(cfg->module_conf, "python respip cachedb iterator") != 0
 		&& strcmp(cfg->module_conf, "python validator cachedb iterator") != 0
+		&& strcmp(cfg->module_conf, "python respip validator cachedb iterator") != 0
 		&& strcmp(cfg->module_conf, "cachedb python iterator") != 0
+		&& strcmp(cfg->module_conf, "respip cachedb python iterator") != 0
 		&& strcmp(cfg->module_conf, "validator cachedb python iterator") != 0
+		&& strcmp(cfg->module_conf, "respip validator cachedb python iterator") != 0
 		&& strcmp(cfg->module_conf, "validator python cachedb iterator") != 0
+		&& strcmp(cfg->module_conf, "respip validator python cachedb iterator") != 0
 #endif
 #ifdef CLIENT_SUBNET
 		&& strcmp(cfg->module_conf, "subnetcache iterator") != 0
+		&& strcmp(cfg->module_conf, "respip subnetcache iterator") != 0
 		&& strcmp(cfg->module_conf, "subnetcache validator iterator") != 0
+		&& strcmp(cfg->module_conf, "respip subnetcache validator iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 subnetcache iterator") != 0
 		&& strcmp(cfg->module_conf, "dns64 subnetcache validator iterator") != 0
 #endif
 #if defined(WITH_PYTHONMODULE) && defined(CLIENT_SUBNET)
 		&& strcmp(cfg->module_conf, "python subnetcache iterator") != 0
+		&& strcmp(cfg->module_conf, "python respip subnetcache iterator") != 0
 		&& strcmp(cfg->module_conf, "subnetcache python iterator") != 0
+		&& strcmp(cfg->module_conf, "respip subnetcache python iterator") != 0
 		&& strcmp(cfg->module_conf, "python subnetcache validator iterator") != 0
+		&& strcmp(cfg->module_conf, "python respip subnetcache validator iterator") != 0
 		&& strcmp(cfg->module_conf, "subnetcache python validator iterator") != 0
+		&& strcmp(cfg->module_conf, "respip subnetcache python validator iterator") != 0
 		&& strcmp(cfg->module_conf, "subnetcache validator python iterator") != 0
+		&& strcmp(cfg->module_conf, "respip subnetcache validator python iterator") != 0
 #endif
 #ifdef USE_IPSECMOD
 		&& strcmp(cfg->module_conf, "ipsecmod iterator") != 0
+		&& strcmp(cfg->module_conf, "ipsecmod respip iterator") != 0
 		&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
+		&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
 #endif
 #if defined(WITH_PYTHONMODULE) && defined(USE_IPSECMOD)
 		&& strcmp(cfg->module_conf, "python ipsecmod iterator") != 0
+		&& strcmp(cfg->module_conf, "python ipsecmod respip iterator") != 0
 		&& strcmp(cfg->module_conf, "ipsecmod python iterator") != 0
+		&& strcmp(cfg->module_conf, "ipsecmod python respip iterator") != 0
 		&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
+		&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
 		&& strcmp(cfg->module_conf, "python ipsecmod validator iterator") != 0
+		&& strcmp(cfg->module_conf, "python ipsecmod respip validator iterator") != 0
 		&& strcmp(cfg->module_conf, "ipsecmod python validator iterator") != 0
+		&& strcmp(cfg->module_conf, "ipsecmod python respip validator iterator") != 0
 		&& strcmp(cfg->module_conf, "ipsecmod validator python iterator") != 0
+		&& strcmp(cfg->module_conf, "ipsecmod respip validator python iterator") != 0
 #endif
+#ifdef USE_IPSET
+		&& strcmp(cfg->module_conf, "validator ipset iterator") != 0
+		&& strcmp(cfg->module_conf, "validator ipset respip iterator") != 0
+		&& strcmp(cfg->module_conf, "ipset iterator") != 0
+		&& strcmp(cfg->module_conf, "ipset respip iterator") != 0
+#endif
 		) {
 		fatal_exit("module conf '%s' is not known to work",
 			cfg->module_conf);
@@ -615,6 +665,7 @@
 				cfg->control_cert_file);
 	}
 
+	donotquerylocalhostcheck(cfg);
 	localzonechecks(cfg);
 	view_and_respipchecks(cfg);
 #ifdef CLIENT_SUBNET
@@ -648,8 +699,9 @@
 static void
 check_auth(struct config_file* cfg)
 {
+	int is_rpz = 0;
 	struct auth_zones* az = auth_zones_create();
-	if(!az || !auth_zones_apply_cfg(az, cfg, 0)) {
+	if(!az || !auth_zones_apply_cfg(az, cfg, 0i, &is_rpz)) {
 		fatal_exit("Could not setup authority zones");
 	}
 	auth_zones_delete(az);
@@ -680,7 +732,7 @@
 		config_delete(cfg);
 		return;
 	}
-	morechecks(cfg, cfgfile);
+	morechecks(cfg);
 	check_mod(cfg, iter_get_funcblock());
 	check_mod(cfg, val_get_funcblock());
 #ifdef WITH_PYTHONMODULE
--- contrib/unbound/smallapp/unbound-control-setup.sh.orig
+++ contrib/unbound/smallapp/unbound-control-setup.sh
@@ -148,8 +148,8 @@
 # echo "empty password is used, simply click OK on the password dialog box."
 # openssl pkcs12 -export -in $CTL_BASE"_trust.pem" -inkey $CTL_BASE.key -name "unbound remote control client cert" -out $CTL_BASE"_browser.pfx" -password "pass:" || error "could not create browser certificate"
 
-# remove unused permissions
-chmod o-rw $SVR_BASE.pem $SVR_BASE.key $CTL_BASE.pem $CTL_BASE.key
+# set desired permissions
+chmod 0640 $SVR_BASE.pem $SVR_BASE.key $CTL_BASE.pem $CTL_BASE.key
 
 # remove crap
 rm -f request.cfg
--- contrib/unbound/smallapp/unbound-control-setup.sh.in.orig
+++ contrib/unbound/smallapp/unbound-control-setup.sh.in
@@ -148,8 +148,8 @@
 # echo "empty password is used, simply click OK on the password dialog box."
 # openssl pkcs12 -export -in $CTL_BASE"_trust.pem" -inkey $CTL_BASE.key -name "unbound remote control client cert" -out $CTL_BASE"_browser.pfx" -password "pass:" || error "could not create browser certificate"
 
-# remove unused permissions
-chmod o-rw $SVR_BASE.pem $SVR_BASE.key $CTL_BASE.pem $CTL_BASE.key
+# set desired permissions
+chmod 0640 $SVR_BASE.pem $SVR_BASE.key $CTL_BASE.pem $CTL_BASE.key
 
 # remove crap
 rm -f request.cfg
--- contrib/unbound/smallapp/unbound-control.c.orig
+++ contrib/unbound/smallapp/unbound-control.c
@@ -62,6 +62,7 @@
 #include "daemon/stats.h"
 #include "sldns/wire2str.h"
 #include "sldns/pkthdr.h"
+#include "services/rpz.h"
 
 #ifdef HAVE_SYS_IPC_H
 #include "sys/ipc.h"
@@ -154,7 +155,11 @@
 	printf("  view_local_zone view name type  	add local-zone in view\n");
 	printf("  view_local_zone_remove view name  	remove local-zone in view\n");
 	printf("  view_local_data view RR...		add local-data in view\n");
+	printf("  view_local_datas view 		add list of local-data to view\n");
+	printf("  					one entry per line read from stdin\n");
 	printf("  view_local_data_remove view name  	remove local-data in view\n");
+	printf("  view_local_datas_remove view 		remove list of local-data from view\n");
+	printf("  					one entry per line read from stdin\n");
 	printf("Version %s\n", PACKAGE_VERSION);
 	printf("BSD licensed, see LICENSE in source package for details.\n");
 	printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
@@ -206,7 +211,7 @@
 		s->svr.num_queries - s->svr.num_queries_missed_cache);
 	PR_UL_NM("num.cachemiss", s->svr.num_queries_missed_cache);
 	PR_UL_NM("num.prefetch", s->svr.num_queries_prefetch);
-	PR_UL_NM("num.zero_ttl", s->svr.zero_ttl_responses);
+	PR_UL_NM("num.expired", s->svr.ans_expired);
 	PR_UL_NM("num.recursivereplies", s->mesh_replies_sent);
 #ifdef USE_DNSCRYPT
     PR_UL_NM("num.dnscrypt.crypted", s->svr.num_query_dnscrypt_crypted);
@@ -245,7 +250,8 @@
 }
 
 /** print memory usage */
-static void print_mem(struct ub_shm_stat_info* shm_stat)
+static void print_mem(struct ub_shm_stat_info* shm_stat,
+	struct ub_stats_info* s)
 {
 	PR_LL("mem.cache.rrset", shm_stat->mem.rrset);
 	PR_LL("mem.cache.message", shm_stat->mem.msg);
@@ -264,6 +270,7 @@
 	PR_LL("mem.cache.dnscrypt_nonce",
 		shm_stat->mem.dnscrypt_nonce);
 #endif
+	PR_LL("mem.streamwait", s->svr.mem_stream_wait);
 }
 
 /** print histogram */
@@ -326,6 +333,7 @@
 	PR_UL("num.query.tcp", s->svr.qtcp);
 	PR_UL("num.query.tcpout", s->svr.qtcp_outgoing);
 	PR_UL("num.query.tls", s->svr.qtls);
+	PR_UL("num.query.tls_resume", s->svr.qtls_resume);
 	PR_UL("num.query.ipv6", s->svr.qipv6);
 
 	/* flags */
@@ -367,6 +375,14 @@
 	PR_UL("rrset.cache.count", s->svr.rrset_cache_count);
 	PR_UL("infra.cache.count", s->svr.infra_cache_count);
 	PR_UL("key.cache.count", s->svr.key_cache_count);
+	/* applied RPZ actions */
+	for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
+		if(i == RPZ_NO_OVERRIDE_ACTION)
+			continue;
+		if(inhibit_zero && s->svr.rpz_action[i] == 0)
+			continue;
+		PR_UL_SUB("num.rpz.action", rpz_action_to_string(i), s->svr.rpz_action[i]);
+	}
 #ifdef USE_DNSCRYPT
 	PR_UL("dnscrypt_shared_secret.cache.count",
 			 s->svr.shared_secret_cache_count);
@@ -397,7 +413,7 @@
 	pr_stats("total", &stats[0]);
 	print_uptime(shm_stat);
 	if(cfg->stat_extended) {
-		print_mem(shm_stat);
+		print_mem(shm_stat, &stats[0]);
 		print_hist(stats);
 		print_extended(stats);
 	}
@@ -418,19 +434,19 @@
 	if(!config_read(cfg, cfgfile, NULL))
 		fatal_exit("could not read config file");
 	/* get shm segments */
-	id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R|SHM_W);
+	id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R);
 	if(id_ctl == -1) {
 		fatal_exit("shmget(%d): %s", cfg->shm_key, strerror(errno));
 	}
-	id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R|SHM_W);
+	id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R);
 	if(id_arr == -1) {
 		fatal_exit("shmget(%d): %s", cfg->shm_key+1, strerror(errno));
 	}
-	shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, 0);
+	shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, SHM_RDONLY);
 	if(shm_stat == (void*)-1) {
 		fatal_exit("shmat(%d): %s", id_ctl, strerror(errno));
 	}
-	stats = (struct ub_stats_info*)shmat(id_arr, NULL, 0);
+	stats = (struct ub_stats_info*)shmat(id_arr, NULL, SHM_RDONLY);
 	if(stats == (void*)-1) {
 		fatal_exit("shmat(%d): %s", id_arr, strerror(errno));
 	}
@@ -488,12 +504,20 @@
 	ctx = SSL_CTX_new(SSLv23_client_method());
 	if(!ctx)
 		ssl_err("could not allocate SSL_CTX pointer");
+#if SSL_OP_NO_SSLv2 != 0
 	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
 		!= SSL_OP_NO_SSLv2)
 		ssl_err("could not set SSL_OP_NO_SSLv2");
+#endif
 	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
 		!= SSL_OP_NO_SSLv3)
 		ssl_err("could not set SSL_OP_NO_SSLv3");
+#if defined(SSL_OP_NO_RENEGOTIATION)
+	/* disable client renegotiation */
+	if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
+		SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION)
+		ssl_err("could not set SSL_OP_NO_RENEGOTIATION");
+#endif
 	if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert))
 		ssl_path_err("Error setting up SSL_CTX client cert", c_cert);
 	if (!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM))
@@ -604,7 +628,7 @@
 	if(!ssl)
 		ssl_err("could not SSL_new");
 	SSL_set_connect_state(ssl);
-	(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+	(void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY);
 	if(!SSL_set_fd(ssl, fd))
 		ssl_err("could not SSL_set_fd");
 	while(1) {
@@ -679,6 +703,28 @@
 	}
 }
 
+/** check args, to see if too many args. Because when a file is sent it
+ * would wait for the terminal, and we can check for too many arguments,
+ * eg. user put arguments on the commandline. */
+static void
+check_args_for_listcmd(int argc, char* argv[])
+{
+	if(argc >= 1 && (strcmp(argv[0], "local_zones") == 0 ||
+		strcmp(argv[0], "local_zones_remove") == 0 ||
+		strcmp(argv[0], "local_datas") == 0 ||
+		strcmp(argv[0], "local_datas_remove") == 0) &&
+		argc >= 2) {
+		fatal_exit("too many arguments for command '%s', "
+			"content is piped in from stdin", argv[0]);
+	}
+	if(argc >= 1 && (strcmp(argv[0], "view_local_datas") == 0 ||
+		strcmp(argv[0], "view_local_datas_remove") == 0) &&
+		argc >= 3) {
+		fatal_exit("too many arguments for command '%s', "
+			"content is piped in from stdin", argv[0]);
+	}
+}
+
 /** send stdin to server */
 static void
 send_file(SSL* ssl, int fd, FILE* in, char* buf, size_t sz)
@@ -717,10 +763,12 @@
 	if(argc == 1 && strcmp(argv[0], "load_cache") == 0) {
 		send_file(ssl, fd, stdin, buf, sizeof(buf));
 	}
-	else if(argc == 1 && (strcmp(argv[0], "local_zones") == 0 ||
+	else if(argc >= 1 && (strcmp(argv[0], "local_zones") == 0 ||
 		strcmp(argv[0], "local_zones_remove") == 0 ||
 		strcmp(argv[0], "local_datas") == 0 ||
-		strcmp(argv[0], "local_datas_remove") == 0)) {
+		strcmp(argv[0], "view_local_datas") == 0 ||
+		strcmp(argv[0], "local_datas_remove") == 0 ||
+		strcmp(argv[0], "view_local_datas_remove") == 0)) {
 		send_file(ssl, fd, stdin, buf, sizeof(buf));
 		send_eof(ssl, fd);
 	}
@@ -841,6 +889,7 @@
 		print_stats_shm(cfgfile);
 		return 0;
 	}
+	check_args_for_listcmd(argc, argv);
 
 #ifdef USE_WINSOCK
 	if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0)
@@ -854,7 +903,9 @@
 	ERR_load_SSL_strings();
 #endif
 #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
+#  ifndef S_SPLINT_S
 	OpenSSL_add_all_algorithms();
+#  endif
 #else
 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
 		| OPENSSL_INIT_ADD_ALL_DIGESTS
--- contrib/unbound/smallapp/unbound-host.c.orig
+++ contrib/unbound/smallapp/unbound-host.c
@@ -426,6 +426,7 @@
 	int c;
 	char* qclass = NULL;
 	char* qtype = NULL;
+	char* use_syslog = NULL;
 	struct ub_ctx* ctx = NULL;
 	int debuglevel = 0;
 	
@@ -486,11 +487,11 @@
 	}
 	if(debuglevel != 0) /* set after possible -C options */
 		check_ub_res(ub_ctx_debuglevel(ctx, debuglevel));
-	if(ub_ctx_get_option(ctx, "use-syslog", &optarg) == 0) {
-		if(strcmp(optarg, "yes") == 0) /* disable use-syslog */
+	if(ub_ctx_get_option(ctx, "use-syslog", &use_syslog) == 0) {
+		if(strcmp(use_syslog, "yes") == 0) /* disable use-syslog */
 			check_ub_res(ub_ctx_set_option(ctx, 
 				"use-syslog:", "no"));
-		free(optarg);
+		free(use_syslog);
 	}
 	argc -= optind;
 	argv += optind;
@@ -505,7 +506,9 @@
 	ERR_load_SSL_strings();
 #endif
 #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
+#  ifndef S_SPLINT_S
 	OpenSSL_add_all_algorithms();
+#  endif
 #else
 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
 		| OPENSSL_INIT_ADD_ALL_DIGESTS
--- contrib/unbound/util/alloc.c.orig
+++ contrib/unbound/util/alloc.c
@@ -376,6 +376,7 @@
 {
 	void* res;
 	if(size == 0) size = 1;
+	log_assert(size <= SIZE_MAX-16);
 	res = malloc(size+16);
 	if(!res) return NULL;
 	unbound_mem_alloc += size;
@@ -398,6 +399,7 @@
 	if(nmemb != 0 && INT_MAX/nmemb < size)
 		return NULL; /* integer overflow check */
 	s = (nmemb*size==0)?(size_t)1:nmemb*size;
+	log_assert(s <= SIZE_MAX-16);
 	res = calloc(1, s+16);
 	if(!res) return NULL;
 	log_info("stat %p=calloc(%u, %u)", res+16, (unsigned)nmemb, (unsigned)size);
@@ -447,6 +449,7 @@
 		/* nothing changes */
 		return ptr;
 	}
+	log_assert(size <= SIZE_MAX-16);
 	res = malloc(size+16);
 	if(!res) return NULL;
 	unbound_mem_alloc += size;
@@ -521,7 +524,9 @@
         const char* func)
 {
 	/*  [prefix .. len .. actual data .. suffix] */
-	void* res = malloc(size+lite_pad*2+sizeof(size_t));
+	void* res;
+	log_assert(size <= SIZE_MAX-(lite_pad*2+sizeof(size_t)));
+	res = malloc(size+lite_pad*2+sizeof(size_t));
 	if(!res) return NULL;
 	memmove(res, lite_pre, lite_pad);
 	memmove(res+lite_pad, &size, sizeof(size_t));
@@ -538,6 +543,7 @@
 	if(nmemb != 0 && INT_MAX/nmemb < size)
 		return NULL; /* integer overflow check */
 	req = nmemb * size;
+	log_assert(req <= SIZE_MAX-(lite_pad*2+sizeof(size_t)));
 	res = malloc(req+lite_pad*2+sizeof(size_t));
 	if(!res) return NULL;
 	memmove(res, lite_pre, lite_pad);
--- contrib/unbound/util/config_file.c.orig
+++ contrib/unbound/util/config_file.c
@@ -59,6 +59,7 @@
 #include "services/cache/infra.h"
 #include "sldns/wire2str.h"
 #include "sldns/parseutil.h"
+#include "iterator/iterator.h"
 #ifdef HAVE_GLOB_H
 # include <glob.h>
 #endif
@@ -75,6 +76,8 @@
 gid_t cfg_gid = (gid_t)-1;
 /** for debug allow small timeout values for fast rollovers */
 int autr_permit_small_holddown = 0;
+/** size (in bytes) of stream wait buffers max */
+size_t stream_wait_max = 4 * 1024 * 1024;
 
 /** global config during parsing */
 struct config_parser_state* cfg_parser = 0;
@@ -118,6 +121,7 @@
 	cfg->log_time_ascii = 0;
 	cfg->log_queries = 0;
 	cfg->log_replies = 0;
+	cfg->log_tag_queryreply = 0;
 	cfg->log_local_actions = 0;
 	cfg->log_servfail = 0;
 #ifndef USE_WINSOCK
@@ -138,6 +142,7 @@
 	cfg->outgoing_num_tcp = 2; /* leaves 64-52=12 for: 4if,1stop,thread4 */
 	cfg->incoming_num_tcp = 2; 
 #endif
+	cfg->stream_wait_size = 4 * 1024 * 1024;
 	cfg->edns_buffer_size = 4096; /* 4k from rfc recommendation */
 	cfg->msg_buffer_size = 65552; /* 64 k + a small margin */
 	cfg->msg_cache_size = 4 * 1024 * 1024;
@@ -152,6 +157,7 @@
 	cfg->max_negative_ttl = 3600;
 	cfg->prefetch = 0;
 	cfg->prefetch_key = 0;
+	cfg->deny_any = 0;
 	cfg->infra_cache_slabs = 4;
 	cfg->infra_cache_numhosts = 10000;
 	cfg->infra_cache_min_rtt = 50;
@@ -167,8 +173,8 @@
 	if(!(cfg->logfile = strdup(""))) goto error_exit;
 	if(!(cfg->pidfile = strdup(PIDFILE))) goto error_exit;
 	if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit;
-	cfg->low_rtt_permil = 0;
-	cfg->low_rtt = 45;
+	cfg->fast_server_permil = 0;
+	cfg->fast_server_num = 3;
 	cfg->donotqueryaddrs = NULL;
 	cfg->donotquery_localhost = 1;
 	cfg->root_hints = NULL;
@@ -194,6 +200,10 @@
 	cfg->client_subnet_always_forward = 0;
 	cfg->max_client_subnet_ipv4 = 24;
 	cfg->max_client_subnet_ipv6 = 56;
+	cfg->min_client_subnet_ipv4 = 0;
+	cfg->min_client_subnet_ipv6 = 0;
+	cfg->max_ecs_tree_size_ipv4 = 100;
+	cfg->max_ecs_tree_size_ipv6 = 100;
 #endif
 	cfg->views = NULL;
 	cfg->acls = NULL;
@@ -236,6 +246,8 @@
 	cfg->serve_expired = 0;
 	cfg->serve_expired_ttl = 0;
 	cfg->serve_expired_ttl_reset = 0;
+	cfg->serve_expired_reply_ttl = 30;
+	cfg->serve_expired_client_timeout = 0;
 	cfg->add_holddown = 30*24*3600;
 	cfg->del_holddown = 30*24*3600;
 	cfg->keep_missing = 366*24*3600; /* one year plus a little leeway */
@@ -245,6 +257,9 @@
 	cfg->neg_cache_size = 1 * 1024 * 1024;
 	cfg->local_zones = NULL;
 	cfg->local_zones_nodefault = NULL;
+#ifdef USE_IPSET
+	cfg->local_zones_ipset = NULL;
+#endif
 	cfg->local_zones_disable_default = 0;
 	cfg->local_data = NULL;
 	cfg->local_zone_overrides = NULL;
@@ -258,6 +273,7 @@
 	cfg->control_use_cert = 1;
 	cfg->minimal_responses = 1;
 	cfg->rrset_roundrobin = 0;
+	cfg->unknown_server_time_limit = 376;
 	cfg->max_udp_size = 4096;
 	if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key"))) 
 		goto error_exit;
@@ -313,12 +329,21 @@
 	cfg->ipsecmod_strict = 0;
 #endif
 #ifdef USE_CACHEDB
-	cfg->cachedb_backend = NULL;
-	cfg->cachedb_secret = NULL;
+	if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
+	if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
+#ifdef USE_REDIS
+	if(!(cfg->redis_server_host = strdup("127.0.0.1"))) goto error_exit;
+	cfg->redis_timeout = 100;
+	cfg->redis_server_port = 6379;
+#endif  /* USE_REDIS */
+#endif  /* USE_CACHEDB */
+#ifdef USE_IPSET
+	cfg->ipset_name_v4 = NULL;
+	cfg->ipset_name_v6 = NULL;
 #endif
 	return cfg;
 error_exit:
-	config_delete(cfg); 
+	config_delete(cfg);
 	return NULL;
 }
 
@@ -476,6 +501,9 @@
 	else S_STRLIST("additional-tls-port:", tls_additional_port)
 	else S_STRLIST("tls-additional-ports:", tls_additional_port)
 	else S_STRLIST("tls-additional-port:", tls_additional_port)
+	else S_STRLIST_APPEND("tls-session-ticket-keys:", tls_session_ticket_keys)
+	else S_STR("tls-ciphers:", tls_ciphers)
+	else S_STR("tls-ciphersuites:", tls_ciphersuites)
 	else S_YNO("interface-automatic:", if_automatic)
 	else S_YNO("use-systemd:", use_systemd)
 	else S_YNO("do-daemonize:", do_daemonize)
@@ -483,6 +511,7 @@
 	else S_NUMBER_NONZERO("outgoing-range:", outgoing_num_ports)
 	else S_SIZET_OR_ZERO("outgoing-num-tcp:", outgoing_num_tcp)
 	else S_SIZET_OR_ZERO("incoming-num-tcp:", incoming_num_tcp)
+	else S_MEMSIZE("stream-wait-size:", stream_wait_size)
 	else S_SIZET_NONZERO("edns-buffer-size:", edns_buffer_size)
 	else S_SIZET_NONZERO("msg-buffer-size:", msg_buffer_size)
 	else S_MEMSIZE("msg-cache-size:", msg_cache_size)
@@ -498,6 +527,7 @@
 	else S_POW2("rrset-cache-slabs:", rrset_cache_slabs)
 	else S_YNO("prefetch:", prefetch)
 	else S_YNO("prefetch-key:", prefetch_key)
+	else S_YNO("deny-any:", deny_any)
 	else if(strcmp(opt, "cache-max-ttl:") == 0)
 	{ IS_NUMBER_OR_ZERO; cfg->max_ttl = atoi(val); MAX_TTL=(time_t)cfg->max_ttl;}
 	else if(strcmp(opt, "cache-max-negative-ttl:") == 0)
@@ -552,15 +582,21 @@
 	else S_YNO("val-log-squelch:", val_log_squelch)
 	else S_YNO("log-queries:", log_queries)
 	else S_YNO("log-replies:", log_replies)
+	else S_YNO("log-tag-queryreply:", log_tag_queryreply)
 	else S_YNO("log-local-actions:", log_local_actions)
 	else S_YNO("log-servfail:", log_servfail)
 	else S_YNO("val-permissive-mode:", val_permissive_mode)
 	else S_YNO("aggressive-nsec:", aggressive_nsec)
 	else S_YNO("ignore-cd-flag:", ignore_cd)
-	else S_YNO("serve-expired:", serve_expired)
-	else if(strcmp(opt, "serve_expired_ttl:") == 0)
+	else if(strcmp(opt, "serve-expired:") == 0)
+	{ IS_YES_OR_NO; cfg->serve_expired = (strcmp(val, "yes") == 0);
+	  SERVE_EXPIRED = cfg->serve_expired; }
+	else if(strcmp(opt, "serve-expired-ttl:") == 0)
 	{ IS_NUMBER_OR_ZERO; cfg->serve_expired_ttl = atoi(val); SERVE_EXPIRED_TTL=(time_t)cfg->serve_expired_ttl;}
 	else S_YNO("serve-expired-ttl-reset:", serve_expired_ttl_reset)
+	else if(strcmp(opt, "serve-expired-reply-ttl:") == 0)
+	{ IS_NUMBER_OR_ZERO; cfg->serve_expired_reply_ttl = atoi(val); SERVE_EXPIRED_REPLY_TTL=(time_t)cfg->serve_expired_reply_ttl;}
+	else S_NUMBER_OR_ZERO("serve-expired-client-timeout:", serve_expired_client_timeout)
 	else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations)
 	else S_UNSIGNED_OR_ZERO("add-holddown:", add_holddown)
 	else S_UNSIGNED_OR_ZERO("del-holddown:", del_holddown)
@@ -573,6 +609,7 @@
 	else S_MEMSIZE("neg-cache-size:", neg_cache_size)
 	else S_YNO("minimal-responses:", minimal_responses)
 	else S_YNO("rrset-roundrobin:", rrset_roundrobin)
+	else S_NUMBER_OR_ZERO("unknown-server-time-limit:", unknown_server_time_limit)
 	else S_STRLIST("local-data:", local_data)
 	else S_YNO("unblock-lan-zones:", unblock_lan_zones)
 	else S_YNO("insecure-lan-zones:", insecure_lan_zones)
@@ -584,7 +621,7 @@
 	else S_STR("control-key-file:", control_key_file)
 	else S_STR("control-cert-file:", control_cert_file)
 	else S_STR("module-config:", module_conf)
-	else S_STR("python-script:", python_script)
+	else S_STRLIST("python-script:", python_script)
 	else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check)
 #ifdef CLIENT_SUBNET
 	/* Can't set max subnet prefix here, since that value is used when
@@ -642,9 +679,8 @@
 	else S_POW2("ratelimit-slabs:", ratelimit_slabs)
 	else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor)
 	else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
-	else S_NUMBER_OR_ZERO("low-rtt:", low_rtt)
-	else S_NUMBER_OR_ZERO("low-rtt-pct:", low_rtt_permil)
-	else S_NUMBER_OR_ZERO("low-rtt-permil:", low_rtt_permil)
+	else S_SIZET_NONZERO("fast-server-num:", fast_server_num)
+	else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil)
 	else S_YNO("qname-minimisation:", qname_minimisation)
 	else S_YNO("qname-minimisation-strict:", qname_minimisation_strict)
 #ifdef USE_IPSECMOD
@@ -683,7 +719,9 @@
 		 * ratelimit-for-domain, ratelimit-below-domain,
 		 * local-zone-tag, access-control-view,
 		 * send-client-subnet, client-subnet-always-forward,
-		 * max-client-subnet-ipv4, max-client-subnet-ipv6, ipsecmod_hook,
+		 * max-client-subnet-ipv4, max-client-subnet-ipv6,
+		 * min-client-subnet-ipv4, min-client-subnet-ipv6,
+		 * max-ecs-tree-size-ipv4, max-ecs-tree-size-ipv6, ipsecmod_hook,
 		 * ipsecmod_whitelist. */
 		return 0;
 	}
@@ -865,6 +903,7 @@
 	else O_DEC(opt, "outgoing-range", outgoing_num_ports)
 	else O_DEC(opt, "outgoing-num-tcp", outgoing_num_tcp)
 	else O_DEC(opt, "incoming-num-tcp", incoming_num_tcp)
+	else O_MEM(opt, "stream-wait-size", stream_wait_size)
 	else O_DEC(opt, "edns-buffer-size", edns_buffer_size)
 	else O_DEC(opt, "msg-buffer-size", msg_buffer_size)
 	else O_MEM(opt, "msg-cache-size", msg_cache_size)
@@ -880,6 +919,7 @@
 	else O_DEC(opt, "rrset-cache-slabs", rrset_cache_slabs)
 	else O_YNO(opt, "prefetch-key", prefetch_key)
 	else O_YNO(opt, "prefetch", prefetch)
+	else O_YNO(opt, "deny-any", deny_any)
 	else O_DEC(opt, "cache-max-ttl", max_ttl)
 	else O_DEC(opt, "cache-max-negative-ttl", max_negative_ttl)
 	else O_DEC(opt, "cache-min-ttl", min_ttl)
@@ -906,6 +946,9 @@
 	else O_STR(opt, "tls-cert-bundle", tls_cert_bundle)
 	else O_YNO(opt, "tls-win-cert", tls_win_cert)
 	else O_LST(opt, "tls-additional-port", tls_additional_port)
+	else O_LST(opt, "tls-session-ticket-keys", tls_session_ticket_keys.first)
+	else O_STR(opt, "tls-ciphers", tls_ciphers)
+	else O_STR(opt, "tls-ciphersuites", tls_ciphersuites)
 	else O_YNO(opt, "use-systemd", use_systemd)
 	else O_YNO(opt, "do-daemonize", do_daemonize)
 	else O_STR(opt, "chroot", chrootdir)
@@ -914,6 +957,7 @@
 	else O_STR(opt, "logfile", logfile)
 	else O_YNO(opt, "log-queries", log_queries)
 	else O_YNO(opt, "log-replies", log_replies)
+	else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply)
 	else O_YNO(opt, "log-local-actions", log_local_actions)
 	else O_YNO(opt, "log-servfail", log_servfail)
 	else O_STR(opt, "pidfile", pidfile)
@@ -945,6 +989,8 @@
 	else O_YNO(opt, "serve-expired", serve_expired)
 	else O_DEC(opt, "serve-expired-ttl", serve_expired_ttl)
 	else O_YNO(opt, "serve-expired-ttl-reset", serve_expired_ttl_reset)
+	else O_DEC(opt, "serve-expired-reply-ttl", serve_expired_reply_ttl)
+	else O_DEC(opt, "serve-expired-client-timeout", serve_expired_client_timeout)
 	else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations)
 	else O_UNS(opt, "add-holddown", add_holddown)
 	else O_UNS(opt, "del-holddown", del_holddown)
@@ -977,11 +1023,16 @@
 	else O_UNS(opt, "val-override-date", val_date_override)
 	else O_YNO(opt, "minimal-responses", minimal_responses)
 	else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin)
+	else O_DEC(opt, "unknown-server-time-limit", unknown_server_time_limit)
 #ifdef CLIENT_SUBNET
 	else O_LST(opt, "send-client-subnet", client_subnet)
 	else O_LST(opt, "client-subnet-zone", client_subnet_zone)
 	else O_DEC(opt, "max-client-subnet-ipv4", max_client_subnet_ipv4)
 	else O_DEC(opt, "max-client-subnet-ipv6", max_client_subnet_ipv6)
+	else O_DEC(opt, "min-client-subnet-ipv4", min_client_subnet_ipv4)
+	else O_DEC(opt, "min-client-subnet-ipv6", min_client_subnet_ipv6)
+	else O_DEC(opt, "max-ecs-tree-size-ipv4", max_ecs_tree_size_ipv4)
+	else O_DEC(opt, "max-ecs-tree-size-ipv6", max_ecs_tree_size_ipv6)
 	else O_YNO(opt, "client-subnet-always-forward:",
 		client_subnet_always_forward)
 #endif
@@ -1024,7 +1075,7 @@
 	else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones)
 	else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
 	else O_DEC(opt, "max-udp-size", max_udp_size)
-	else O_STR(opt, "python-script", python_script)
+	else O_LST(opt, "python-script", python_script)
 	else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check)
 	else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
 	else O_DEC(opt, "ratelimit", ratelimit)
@@ -1036,9 +1087,8 @@
 	else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain)
 	else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor)
 	else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
-	else O_DEC(opt, "low-rtt", low_rtt)
-	else O_DEC(opt, "low-rtt-pct", low_rtt_permil)
-	else O_DEC(opt, "low-rtt-permil", low_rtt_permil)
+	else O_DEC(opt, "fast-server-num", fast_server_num)
+	else O_DEC(opt, "fast-server-permil", fast_server_permil)
 	else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
 	else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
 	else O_YNO(opt, "qname-minimisation", qname_minimisation)
@@ -1062,6 +1112,15 @@
 #ifdef USE_CACHEDB
 	else O_STR(opt, "backend", cachedb_backend)
 	else O_STR(opt, "secret-seed", cachedb_secret)
+#ifdef USE_REDIS
+	else O_STR(opt, "redis-server-host", redis_server_host)
+	else O_DEC(opt, "redis-server-port", redis_server_port)
+	else O_DEC(opt, "redis-timeout", redis_timeout)
+#endif  /* USE_REDIS */
+#endif  /* USE_CACHEDB */
+#ifdef USE_IPSET
+	else O_STR(opt, "name-v4", ipset_name_v4)
+	else O_STR(opt, "name-v6", ipset_name_v6)
 #endif
 	/* not here:
 	 * outgoing-permit, outgoing-avoid - have list of ports
@@ -1239,6 +1298,10 @@
 	config_delstrlist(p->urls);
 	config_delstrlist(p->allow_notify);
 	free(p->zonefile);
+	free(p->rpz_taglist);
+	free(p->rpz_action_override);
+	free(p->rpz_cname);
+	free(p->rpz_log_name);
 	free(p);
 }
 
@@ -1281,6 +1344,9 @@
 	free(p->name);
 	config_deldblstrlist(p->local_zones);
 	config_delstrlist(p->local_zones_nodefault);
+#ifdef USE_IPSET
+	config_delstrlist(p->local_zones_ipset);
+#endif
 	config_delstrlist(p->local_data);
 	free(p);
 }
@@ -1335,7 +1401,13 @@
 	free(cfg->ssl_service_pem);
 	free(cfg->tls_cert_bundle);
 	config_delstrlist(cfg->tls_additional_port);
-	free(cfg->log_identity);
+	config_delstrlist(cfg->tls_session_ticket_keys.first);
+	free(cfg->tls_ciphers);
+	free(cfg->tls_ciphersuites);
+	if(cfg->log_identity) {
+		log_ident_revert_to_default();
+		free(cfg->log_identity);
+	}
 	config_del_strarray(cfg->ifs, cfg->num_ifs);
 	config_del_strarray(cfg->out_ifs, cfg->num_out_ifs);
 	config_delstubs(cfg->stubs);
@@ -1352,7 +1424,6 @@
 	free(cfg->version);
 	free(cfg->module_conf);
 	free(cfg->outgoing_avail_ports);
-	free(cfg->python_script);
 	config_delstrlist(cfg->caps_whitelist);
 	config_delstrlist(cfg->private_address);
 	config_delstrlist(cfg->private_domain);
@@ -1368,6 +1439,9 @@
 	free(cfg->val_nsec3_key_iterations);
 	config_deldblstrlist(cfg->local_zones);
 	config_delstrlist(cfg->local_zones_nodefault);
+#ifdef USE_IPSET
+	config_delstrlist(cfg->local_zones_ipset);
+#endif
 	config_delstrlist(cfg->local_data);
 	config_deltrplstrlist(cfg->local_zone_overrides);
 	config_del_strarray(cfg->tagname, cfg->num_tags);
@@ -1388,6 +1462,7 @@
 	free(cfg->dnstap_version);
 	config_deldblstrlist(cfg->ratelimit_for_domain);
 	config_deldblstrlist(cfg->ratelimit_below_domain);
+	config_delstrlist(cfg->python_script);
 #ifdef USE_IPSECMOD
 	free(cfg->ipsecmod_hook);
 	config_delstrlist(cfg->ipsecmod_whitelist);
@@ -1395,6 +1470,13 @@
 #ifdef USE_CACHEDB
 	free(cfg->cachedb_backend);
 	free(cfg->cachedb_secret);
+#ifdef USE_REDIS
+	free(cfg->redis_server_host);
+#endif  /* USE_REDIS */
+#endif  /* USE_CACHEDB */
+#ifdef USE_IPSET
+	free(cfg->ipset_name_v4);
+	free(cfg->ipset_name_v6);
 #endif
 	free(cfg);
 }
@@ -1598,6 +1680,31 @@
 	return 1;
 }
 
+int
+cfg_strlist_append_ex(struct config_strlist** head, char* item)
+{
+	struct config_strlist *s;
+	if(!item || !head)
+		return 0;
+	s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist));
+	if(!s)
+		return 0;
+	s->str = item;
+	s->next = NULL;
+	
+	if (*head==NULL) {
+		*head = s;
+	} else {
+		struct config_strlist *last = *head;
+		while (last->next!=NULL) {
+		    last = last->next;
+		}
+		last->next = s;
+	}
+	
+	return 1;  
+}
+
 int 
 cfg_str2list_insert(struct config_str2list** head, char* item, char* i2)
 {
@@ -1864,7 +1971,7 @@
 	return strdup(buf);
 }
 
-int taglist_intersect(uint8_t* list1, size_t list1len, uint8_t* list2,
+int taglist_intersect(uint8_t* list1, size_t list1len, const uint8_t* list2,
 	size_t list2len)
 {
 	size_t i;
@@ -1882,14 +1989,19 @@
 {
 	MAX_TTL = (time_t)config->max_ttl;
 	MIN_TTL = (time_t)config->min_ttl;
+	SERVE_EXPIRED = config->serve_expired;
 	SERVE_EXPIRED_TTL = (time_t)config->serve_expired_ttl;
+	SERVE_EXPIRED_REPLY_TTL = (time_t)config->serve_expired_reply_ttl;
 	MAX_NEG_TTL = (time_t)config->max_negative_ttl;
 	RTT_MIN_TIMEOUT = config->infra_cache_min_rtt;
 	EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
 	MINIMAL_RESPONSES = config->minimal_responses;
 	RRSET_ROUNDROBIN = config->rrset_roundrobin;
+	LOG_TAG_QUERYREPLY = config->log_tag_queryreply;
+	UNKNOWN_SERVER_NICENESS = config->unknown_server_time_limit;
 	log_set_time_asc(config->log_time_ascii);
 	autr_permit_small_holddown = config->permit_small_holddown;
+	stream_wait_max = config->stream_wait_size;
 }
 
 void config_lookup_uid(struct config_file* cfg)
@@ -2072,6 +2184,11 @@
 	if(strcmp(type, "nodefault")==0) {
 		return cfg_strlist_insert(&cfg->local_zones_nodefault, 
 			strdup(name));
+#ifdef USE_IPSET
+	} else if(strcmp(type, "ipset")==0) {
+		return cfg_strlist_insert(&cfg->local_zones_ipset, 
+			strdup(name));
+#endif
 	} else {
 		return cfg_str2list_insert(&cfg->local_zones, strdup(buf),
 			strdup(type));
@@ -2346,3 +2463,4 @@
 	if(cfg->control_ifs.first->str[0] == 0) return 1;
 	return (cfg->control_ifs.first->str[0] != '/');
 }
+
--- contrib/unbound/util/config_file.h.orig
+++ contrib/unbound/util/config_file.h
@@ -120,6 +120,12 @@
 	int tls_win_cert;
 	/** additional tls ports */
 	struct config_strlist* tls_additional_port;
+	/** secret key used to encrypt and decrypt TLS session ticket */
+	struct config_strlist_head tls_session_ticket_keys;
+	/** TLS ciphers */
+	char* tls_ciphers;
+	/** TLS chiphersuites (TLSv1.3) */
+	char* tls_ciphersuites;
 
 	/** outgoing port range number of ports (per thread) */
 	int outgoing_num_ports;
@@ -132,6 +138,8 @@
 
 	/** EDNS buffer size to use */
 	size_t edns_buffer_size;
+	/** size of the stream wait buffers, max */
+	size_t stream_wait_size;
 	/** number of bytes buffer size for DNS messages */
 	size_t msg_buffer_size;
 	/** size of the message cache */
@@ -159,10 +167,11 @@
 
 	/** the target fetch policy for the iterator */
 	char* target_fetch_policy;
-	/** percent*10, how many times in 1000 to pick low rtt destinations */
-	int low_rtt_permil;
-	/** what time in msec is a low rtt destination */
-	int low_rtt;
+	/** percent*10, how many times in 1000 to pick from the fastest
+	 * destinations */
+	int fast_server_permil;
+	/** number of fastest server to select from */
+	size_t fast_server_num;
 
 	/** automatic interface for incoming messages. Uses ipv6 remapping,
 	 * and recvmsg/sendmsg ancillary data to detect interfaces, boolean */
@@ -214,6 +223,12 @@
 	/** Subnet length we are willing to give up privacy for */
 	uint8_t max_client_subnet_ipv4;
 	uint8_t max_client_subnet_ipv6;
+	/** Minimum subnet length we are willing to answer */
+	uint8_t min_client_subnet_ipv4;
+	uint8_t min_client_subnet_ipv6;
+	/** Max number of nodes in the ECS radix tree */
+	uint32_t max_ecs_tree_size_ipv4;
+	uint32_t max_ecs_tree_size_ipv6;
 #endif
 	/** list of access control entries, linked list */
 	struct config_str2list* acls;
@@ -257,6 +272,8 @@
 	int prefetch;
 	/** if prefetching of DNSKEYs should be performed. */
 	int prefetch_key;
+	/** deny queries of type ANY with an empty answer */
+	int deny_any;
 
 	/** chrootdir, if not "" or chroot will be done */
 	char* chrootdir;
@@ -277,6 +294,8 @@
 	int log_queries;
 	/** log replies with one line per reply */
 	int log_replies;
+	/** tag log_queries and log_replies for filtering */
+	int log_tag_queryreply;
 	/** log every local-zone hit **/
 	int log_local_actions;
 	/** log servfails with a reason */
@@ -343,6 +362,11 @@
 	int serve_expired_ttl;
 	/** reset serve expired TTL after failed update attempt */
 	int serve_expired_ttl_reset;
+	/** TTL for the serve expired replies */
+	int serve_expired_reply_ttl;
+	/** serve expired entries only after trying to update the entries and this
+	 *  timeout (in milliseconds) is reached */
+	int serve_expired_client_timeout;
 	/** nsec3 maximum iterations per key size, string */
 	char* val_nsec3_key_iterations;
 	/** autotrust add holddown time, in seconds */
@@ -365,6 +389,10 @@
 	struct config_str2list* local_zones;
 	/** local zones nodefault list */
 	struct config_strlist* local_zones_nodefault;
+#ifdef USE_IPSET
+	/** local zones ipset list */
+	struct config_strlist* local_zones_ipset;
+#endif
 	/** do not add any default local zone */
 	int local_zones_disable_default;
 	/** local data RRs configured */
@@ -414,7 +442,7 @@
 	char* control_cert_file;
 
 	/** Python script file */
-	char* python_script;
+	struct config_strlist* python_script;
 
 	/** Use systemd socket activation. */
 	int use_systemd;
@@ -428,6 +456,9 @@
 	/* RRSet roundrobin */
 	int rrset_roundrobin;
 
+	/* wait time for unknown server in msec */
+	int unknown_server_time_limit;
+
 	/* maximum UDP response size */
 	size_t max_udp_size;
 
@@ -553,6 +584,12 @@
 	int redis_timeout;
 #endif
 #endif
+
+	/* ipset module */
+#ifdef USE_IPSET
+	char* ipset_name_v4;
+	char* ipset_name_v6;
+#endif
 };
 
 /** from cfg username, after daemonize setup performed */
@@ -561,6 +598,8 @@
 extern gid_t cfg_gid;
 /** debug and enable small timeouts */
 extern int autr_permit_small_holddown;
+/** size (in bytes) of stream wait buffers max */
+extern size_t stream_wait_max;
 
 /**
  * Stub config options
@@ -607,6 +646,21 @@
 	/** fallback to recursion to authorities if zone expired and other
 	 * reasons perhaps (like, query bogus) */
 	int fallback_enabled;
+	/** this zone is used to create local-zone policies */
+	int isrpz;
+	/** rpz tags (or NULL) */
+	uint8_t* rpz_taglist;
+	/** length of the taglist (in bytes) */
+	size_t rpz_taglistlen;
+	/** Override RPZ action for this zone, regardless of zone content */
+	char* rpz_action_override;
+	/** Log when this RPZ policy is applied */
+	int rpz_log;
+	/** Display this name in the log when RPZ policy is applied */
+	char* rpz_log_name;
+	/** Always reply with this CNAME target if the cname override action is
+	 * used */
+	char* rpz_cname;
 };
 
 /**
@@ -623,6 +677,10 @@
 	struct config_strlist* local_data;
 	/** local zones nodefault list */
 	struct config_strlist* local_zones_nodefault;
+#ifdef USE_IPSET
+	/** local zones ipset list */
+	struct config_strlist* local_zones_ipset;
+#endif
 	/** Fallback to global local_zones when there is no match in the view
 	 * view specific tree. 1 for yes, 0 for no */	
 	int isfirst;
@@ -797,6 +855,14 @@
 int cfg_strlist_append(struct config_strlist_head* list, char* item);
 
 /**
+ * Searches the end of a string list and appends the given text.
+ * @param head: pointer to strlist head variable.
+ * @param item: new item. malloced by caller. if NULL the insertion fails.
+ * @return true on success.
+ */
+int cfg_strlist_append_ex(struct config_strlist** head, char* item);
+
+/**
  * Find string in strlist.
  * @param head: pointer to strlist head variable.
  * @param item: the item to search for.
@@ -997,7 +1063,7 @@
  * @param list2len: length in bytes of second list.
  * @return true if there are tags in common, 0 if not.
  */
-int taglist_intersect(uint8_t* list1, size_t list1len, uint8_t* list2,
+int taglist_intersect(uint8_t* list1, size_t list1len, const uint8_t* list2,
 	size_t list2len);
 
 /**
@@ -1157,3 +1223,4 @@
 extern int fake_dsa, fake_sha1;
 
 #endif /* UTIL_CONFIG_FILE_H */
+
--- contrib/unbound/util/configlexer.lex.orig
+++ contrib/unbound/util/configlexer.lex
@@ -113,8 +113,7 @@
 	/* check for wildcards */
 #ifdef HAVE_GLOB
 	glob_t g;
-	size_t i;
-	int r, flags;
+	int i, r, flags;
 	if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') &&
 		!strchr(filename, '{') && !strchr(filename, '~'))) {
 		flags = 0
@@ -121,9 +120,8 @@
 #ifdef GLOB_ERR
 			| GLOB_ERR
 #endif
-#ifdef GLOB_NOSORT
-			| GLOB_NOSORT
-#endif
+			 /* do not set GLOB_NOSORT so the results are sorted
+			    and in a predictable order. */
 #ifdef GLOB_BRACE
 			| GLOB_BRACE
 #endif
@@ -146,7 +144,7 @@
 			return;
 		}
 		/* process files found, if any */
-		for(i=0; i<(size_t)g.gl_pathc; i++) {
+		for(i=(int)g.gl_pathc-1; i>=0; i--) {
 			config_start_include(g.gl_pathv[i]);
 		}
 		globfree(&g);
@@ -247,6 +245,9 @@
 additional-tls-port{COLON}	{ YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
 tls-additional-ports{COLON}	{ YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
 tls-additional-port{COLON}	{ YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
+tls-session-ticket-keys{COLON}	{ YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) }
+tls-ciphers{COLON}		{ YDVAR(1, VAR_TLS_CIPHERS) }
+tls-ciphersuites{COLON}		{ YDVAR(1, VAR_TLS_CIPHERSUITES) }
 use-systemd{COLON}		{ YDVAR(1, VAR_USE_SYSTEMD) }
 do-daemonize{COLON}		{ YDVAR(1, VAR_DO_DAEMONIZE) }
 interface{COLON}		{ YDVAR(1, VAR_INTERFACE) }
@@ -264,6 +265,7 @@
 logfile{COLON}			{ YDVAR(1, VAR_LOGFILE) }
 pidfile{COLON}			{ YDVAR(1, VAR_PIDFILE) }
 root-hints{COLON}		{ YDVAR(1, VAR_ROOT_HINTS) }
+stream-wait-size{COLON}		{ YDVAR(1, VAR_STREAM_WAIT_SIZE) }
 edns-buffer-size{COLON}		{ YDVAR(1, VAR_EDNS_BUFFER_SIZE) }
 msg-buffer-size{COLON}		{ YDVAR(1, VAR_MSG_BUFFER_SIZE) }
 msg-cache-size{COLON}		{ YDVAR(1, VAR_MSG_CACHE_SIZE) }
@@ -297,6 +299,7 @@
 private-domain{COLON}		{ YDVAR(1, VAR_PRIVATE_DOMAIN) }
 prefetch-key{COLON}		{ YDVAR(1, VAR_PREFETCH_KEY) }
 prefetch{COLON}			{ YDVAR(1, VAR_PREFETCH) }
+deny-any{COLON}			{ YDVAR(1, VAR_DENY_ANY) }
 stub-zone{COLON}		{ YDVAR(0, VAR_STUB_ZONE) }
 name{COLON}			{ YDVAR(1, VAR_NAME) }
 stub-addr{COLON}		{ YDVAR(1, VAR_STUB_ADDR) }
@@ -314,6 +317,12 @@
 forward-ssl-upstream{COLON}	{ YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) }
 forward-tls-upstream{COLON}	{ YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) }
 auth-zone{COLON}		{ YDVAR(0, VAR_AUTH_ZONE) }
+rpz{COLON}			{ YDVAR(0, VAR_RPZ) }
+tags{COLON}			{ YDVAR(1, VAR_TAGS) }
+rpz-action-override{COLON}	{ YDVAR(1, VAR_RPZ_ACTION_OVERRIDE) }
+rpz-cname-override{COLON}	{ YDVAR(1, VAR_RPZ_CNAME_OVERRIDE) }
+rpz-log{COLON}			{ YDVAR(1, VAR_RPZ_LOG) }
+rpz-log-name{COLON}		{ YDVAR(1, VAR_RPZ_LOG_NAME) }
 zonefile{COLON}			{ YDVAR(1, VAR_ZONEFILE) }
 master{COLON}			{ YDVAR(1, VAR_MASTER) }
 url{COLON}			{ YDVAR(1, VAR_URL) }
@@ -332,6 +341,10 @@
 client-subnet-opcode{COLON}	{ YDVAR(1, VAR_CLIENT_SUBNET_OPCODE) }
 max-client-subnet-ipv4{COLON}	{ YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV4) }
 max-client-subnet-ipv6{COLON}	{ YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV6) }
+min-client-subnet-ipv4{COLON}	{ YDVAR(1, VAR_MIN_CLIENT_SUBNET_IPV4) }
+min-client-subnet-ipv6{COLON}	{ YDVAR(1, VAR_MIN_CLIENT_SUBNET_IPV6) }
+max-ecs-tree-size-ipv4{COLON}	{ YDVAR(1, VAR_MAX_ECS_TREE_SIZE_IPV4) }
+max-ecs-tree-size-ipv6{COLON}	{ YDVAR(1, VAR_MAX_ECS_TREE_SIZE_IPV6) }
 hide-identity{COLON}		{ YDVAR(1, VAR_HIDE_IDENTITY) }
 hide-version{COLON}		{ YDVAR(1, VAR_HIDE_VERSION) }
 hide-trustanchor{COLON}		{ YDVAR(1, VAR_HIDE_TRUSTANCHOR) }
@@ -357,6 +370,8 @@
 serve-expired{COLON}		{ YDVAR(1, VAR_SERVE_EXPIRED) }
 serve-expired-ttl{COLON}	{ YDVAR(1, VAR_SERVE_EXPIRED_TTL) }
 serve-expired-ttl-reset{COLON}	{ YDVAR(1, VAR_SERVE_EXPIRED_TTL_RESET) }
+serve-expired-reply-ttl{COLON}	{ YDVAR(1, VAR_SERVE_EXPIRED_REPLY_TTL) }
+serve-expired-client-timeout{COLON}	{ YDVAR(1, VAR_SERVE_EXPIRED_CLIENT_TIMEOUT) }
 fake-dsa{COLON}			{ YDVAR(1, VAR_FAKE_DSA) }
 fake-sha1{COLON}		{ YDVAR(1, VAR_FAKE_SHA1) }
 val-log-level{COLON}		{ YDVAR(1, VAR_VAL_LOG_LEVEL) }
@@ -374,6 +389,7 @@
 log-time-ascii{COLON}		{ YDVAR(1, VAR_LOG_TIME_ASCII) }
 log-queries{COLON}		{ YDVAR(1, VAR_LOG_QUERIES) }
 log-replies{COLON}		{ YDVAR(1, VAR_LOG_REPLIES) }
+log-tag-queryreply{COLON}	{ YDVAR(1, VAR_LOG_TAG_QUERYREPLY) }
 log-local-actions{COLON}       { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) }
 log-servfail{COLON}		{ YDVAR(1, VAR_LOG_SERVFAIL) }
 local-zone{COLON}		{ YDVAR(2, VAR_LOCAL_ZONE) }
@@ -400,6 +416,7 @@
 domain-insecure{COLON}		{ YDVAR(1, VAR_DOMAIN_INSECURE) }
 minimal-responses{COLON}	{ YDVAR(1, VAR_MINIMAL_RESPONSES) }
 rrset-roundrobin{COLON}		{ YDVAR(1, VAR_RRSET_ROUNDROBIN) }
+unknown-server-time-limit{COLON} { YDVAR(1, VAR_UNKNOWN_SERVER_TIME_LIMIT) }
 max-udp-size{COLON}		{ YDVAR(1, VAR_MAX_UDP_SIZE) }
 dns64-prefix{COLON}		{ YDVAR(1, VAR_DNS64_PREFIX) }
 dns64-synthall{COLON}		{ YDVAR(1, VAR_DNS64_SYNTHALL) }
@@ -442,8 +459,10 @@
 ip-ratelimit-factor{COLON}		{ YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
 ratelimit-factor{COLON}		{ YDVAR(1, VAR_RATELIMIT_FACTOR) }
 low-rtt{COLON}			{ YDVAR(1, VAR_LOW_RTT) }
-low-rtt-pct{COLON}		{ YDVAR(1, VAR_LOW_RTT_PERMIL) }
-low-rtt-permil{COLON}		{ YDVAR(1, VAR_LOW_RTT_PERMIL) }
+fast-server-num{COLON}		{ YDVAR(1, VAR_FAST_SERVER_NUM) }
+low-rtt-pct{COLON}		{ YDVAR(1, VAR_FAST_SERVER_PERMIL) }
+low-rtt-permil{COLON}		{ YDVAR(1, VAR_FAST_SERVER_PERMIL) }
+fast-server-permil{COLON}	{ YDVAR(1, VAR_FAST_SERVER_PERMIL) }
 response-ip-tag{COLON}		{ YDVAR(2, VAR_RESPONSE_IP_TAG) }
 response-ip{COLON}		{ YDVAR(2, VAR_RESPONSE_IP) }
 response-ip-data{COLON}		{ YDVAR(2, VAR_RESPONSE_IP_DATA) }
@@ -472,6 +491,9 @@
 redis-server-host{COLON}	{ YDVAR(1, VAR_CACHEDB_REDISHOST) }
 redis-server-port{COLON}	{ YDVAR(1, VAR_CACHEDB_REDISPORT) }
 redis-timeout{COLON}		{ YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
+ipset{COLON}			{ YDVAR(0, VAR_IPSET) }
+name-v4{COLON}			{ YDVAR(1, VAR_IPSET_NAME_V4) }
+name-v6{COLON}			{ YDVAR(1, VAR_IPSET_NAME_V6) }
 udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
 tcp-connection-limit{COLON}	{ YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
 <INITIAL,val>{NEWLINE}		{ LEXOUT(("NL\n")); cfg_parser->line++; }
--- contrib/unbound/util/configparser.y.orig
+++ contrib/unbound/util/configparser.y
@@ -135,6 +135,8 @@
 %token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE
 %token VAR_CLIENT_SUBNET_ALWAYS_FORWARD VAR_CLIENT_SUBNET_OPCODE
 %token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6
+%token VAR_MIN_CLIENT_SUBNET_IPV4 VAR_MIN_CLIENT_SUBNET_IPV6
+%token VAR_MAX_ECS_TREE_SIZE_IPV4 VAR_MAX_ECS_TREE_SIZE_IPV6
 %token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
 %token VAR_QNAME_MINIMISATION VAR_QNAME_MINIMISATION_STRICT VAR_IP_FREEBIND
 %token VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG VAR_ACCESS_CONTROL_TAG
@@ -141,10 +143,11 @@
 %token VAR_LOCAL_ZONE_OVERRIDE VAR_ACCESS_CONTROL_TAG_ACTION
 %token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
 %token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_SERVE_EXPIRED_TTL
-%token VAR_SERVE_EXPIRED_TTL_RESET VAR_FAKE_DSA VAR_FAKE_SHA1
-%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
-%token VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
-%token VAR_ROOT_KEY_SENTINEL
+%token VAR_SERVE_EXPIRED_TTL_RESET VAR_SERVE_EXPIRED_REPLY_TTL
+%token VAR_SERVE_EXPIRED_CLIENT_TIMEOUT VAR_FAKE_DSA
+%token VAR_FAKE_SHA1 VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR
+%token VAR_TRUST_ANCHOR_SIGNALING VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD
+%token VAR_SHM_ENABLE VAR_SHM_KEY VAR_ROOT_KEY_SENTINEL
 %token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
 %token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
 %token VAR_DNSCRYPT_PROVIDER_CERT_ROTATED
@@ -159,8 +162,14 @@
 %token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
 %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
 %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
+%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
 %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
-%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL
+%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
+%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
+%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
+%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
+%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
+%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -168,7 +177,8 @@
 	forwardstart contents_forward | pythonstart contents_py | 
 	rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
 	dnscstart contents_dnsc | cachedbstart contents_cachedb |
-	authstart contents_auth
+	ipsetstart contents_ipset | authstart contents_auth |
+	rpzstart contents_rpz
 	;
 
 /* server: declaration */
@@ -237,6 +247,8 @@
 	server_client_subnet_zone | server_client_subnet_always_forward |
 	server_client_subnet_opcode |
 	server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
+	server_min_client_subnet_ipv4 | server_min_client_subnet_ipv6 |
+	server_max_ecs_tree_size_ipv4 | server_max_ecs_tree_size_ipv6 |
 	server_caps_whitelist | server_cache_max_negative_ttl |
 	server_permit_small_holddown | server_qname_minimisation |
 	server_ip_freebind | server_define_tag | server_local_zone_tag |
@@ -245,6 +257,7 @@
 	server_access_control_tag_data | server_access_control_view |
 	server_qname_minimisation_strict | server_serve_expired |
 	server_serve_expired_ttl | server_serve_expired_ttl_reset |
+	server_serve_expired_reply_ttl | server_serve_expired_client_timeout |
 	server_fake_dsa | server_log_identity | server_use_systemd |
 	server_response_ip_tag | server_response_ip | server_response_ip_data |
 	server_shm_enable | server_shm_key | server_fake_sha1 |
@@ -255,8 +268,11 @@
 	server_ipsecmod_whitelist | server_ipsecmod_strict |
 	server_udp_upstream_without_downstream | server_aggressive_nsec |
 	server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
-	server_low_rtt_permil | server_tls_win_cert |
-	server_tcp_connection_limit | server_log_servfail
+	server_fast_server_permil | server_fast_server_num  | server_tls_win_cert |
+	server_tcp_connection_limit | server_log_servfail | server_deny_any |
+	server_unknown_server_time_limit | server_log_tag_queryreply |
+	server_stream_wait_size | server_tls_ciphers |
+	server_tls_ciphersuites | server_tls_session_ticket_keys
 	;
 stubstart: VAR_STUB_ZONE
 	{
@@ -323,6 +339,7 @@
 			s->for_downstream = 1;
 			s->for_upstream = 1;
 			s->fallback_enabled = 0;
+			s->isrpz = 0;
 		} else 
 			yyerror("out of memory");
 	}
@@ -333,6 +350,92 @@
 	auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
 	auth_allow_notify
 	;
+
+rpz_tag: VAR_TAGS STRING_ARG
+	{
+		uint8_t* bitlist;
+		size_t len = 0;
+		OUTYY(("P(server_local_zone_tag:%s)\n", $2));
+		bitlist = config_parse_taglist(cfg_parser->cfg, $2,
+			&len);
+		free($2);
+		if(!bitlist) {
+			yyerror("could not parse tags, (define-tag them first)");
+		}
+		if(bitlist) {
+			cfg_parser->cfg->auths->rpz_taglist = bitlist;
+			cfg_parser->cfg->auths->rpz_taglistlen = len;
+
+		}
+	}
+	;
+
+rpz_action_override: VAR_RPZ_ACTION_OVERRIDE STRING_ARG
+	{
+		OUTYY(("P(rpz_action_override:%s)\n", $2));
+		if(strcmp($2, "nxdomain")!=0 && strcmp($2, "nodata")!=0 &&
+		   strcmp($2, "passthru")!=0 && strcmp($2, "drop")!=0 &&
+		   strcmp($2, "cname")!=0 && strcmp($2, "disabled")!=0) {
+			yyerror("rpz-action-override action: expected nxdomain, "
+				"nodata, passthru, drop, cname or disabled");
+			free($2);
+			cfg_parser->cfg->auths->rpz_action_override = NULL;
+		}
+		else {
+			cfg_parser->cfg->auths->rpz_action_override = $2;
+		}
+	}
+	;
+
+rpz_cname_override: VAR_RPZ_CNAME_OVERRIDE STRING_ARG
+	{
+		OUTYY(("P(rpz_cname_override:%s)\n", $2));
+		free(cfg_parser->cfg->auths->rpz_cname);
+		cfg_parser->cfg->auths->rpz_cname = $2;
+	}
+	;
+
+rpz_log: VAR_RPZ_LOG STRING_ARG
+	{
+		OUTYY(("P(rpz_log:%s)\n", $2));
+		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+			yyerror("expected yes or no.");
+		else cfg_parser->cfg->auths->rpz_log = (strcmp($2, "yes")==0);
+		free($2);
+	}
+	;
+
+rpz_log_name: VAR_RPZ_LOG_NAME STRING_ARG
+	{
+		OUTYY(("P(rpz_log_name:%s)\n", $2));
+		free(cfg_parser->cfg->auths->rpz_log_name);
+		cfg_parser->cfg->auths->rpz_log_name = $2;
+	}
+	;
+
+rpzstart: VAR_RPZ
+	{
+		struct config_auth* s;
+		OUTYY(("\nP(rpz:)\n")); 
+		s = (struct config_auth*)calloc(1, sizeof(struct config_auth));
+		if(s) {
+			s->next = cfg_parser->cfg->auths;
+			cfg_parser->cfg->auths = s;
+			/* defaults for RPZ auth zone */
+			s->for_downstream = 0;
+			s->for_upstream = 0;
+			s->fallback_enabled = 0;
+			s->isrpz = 1;
+		} else 
+			yyerror("out of memory");
+	}
+	;
+contents_rpz: contents_rpz content_rpz 
+	| ;
+content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url |
+	   auth_allow_notify | rpz_action_override | rpz_cname_override |
+	   rpz_log | rpz_log_name
+	;
 server_num_threads: VAR_NUM_THREADS STRING_ARG 
 	{ 
 		OUTYY(("P(server_num_threads:%s)\n", $2)); 
@@ -417,6 +520,7 @@
 			fatal_exit("out of memory adding client-subnet");
 	#else
 		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+		free($2);
 	#endif
 	}
 	;
@@ -429,6 +533,7 @@
 			fatal_exit("out of memory adding client-subnet-zone");
 	#else
 		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+		free($2);
 	#endif
 	}
 	;
@@ -493,6 +598,70 @@
 		free($2);
 	}
 	;
+server_min_client_subnet_ipv4: VAR_MIN_CLIENT_SUBNET_IPV4 STRING_ARG
+	{
+	#ifdef CLIENT_SUBNET
+		OUTYY(("P(min_client_subnet_ipv4:%s)\n", $2));
+		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+			yyerror("IPv4 subnet length expected");
+		else if (atoi($2) > 32)
+			cfg_parser->cfg->min_client_subnet_ipv4 = 32;
+		else if (atoi($2) < 0)
+			cfg_parser->cfg->min_client_subnet_ipv4 = 0;
+		else cfg_parser->cfg->min_client_subnet_ipv4 = (uint8_t)atoi($2);
+	#else
+		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+	#endif
+		free($2);
+	}
+	;
+server_min_client_subnet_ipv6: VAR_MIN_CLIENT_SUBNET_IPV6 STRING_ARG
+	{
+	#ifdef CLIENT_SUBNET
+		OUTYY(("P(min_client_subnet_ipv6:%s)\n", $2));
+		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+			yyerror("Ipv6 subnet length expected");
+		else if (atoi($2) > 128)
+			cfg_parser->cfg->min_client_subnet_ipv6 = 128;
+		else if (atoi($2) < 0)
+			cfg_parser->cfg->min_client_subnet_ipv6 = 0;
+		else cfg_parser->cfg->min_client_subnet_ipv6 = (uint8_t)atoi($2);
+	#else
+		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+	#endif
+		free($2);
+	}
+	;
+server_max_ecs_tree_size_ipv4: VAR_MAX_ECS_TREE_SIZE_IPV4 STRING_ARG
+	{
+	#ifdef CLIENT_SUBNET
+		OUTYY(("P(max_ecs_tree_size_ipv4:%s)\n", $2));
+		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+			yyerror("IPv4 ECS tree size expected");
+		else if (atoi($2) < 0)
+			cfg_parser->cfg->max_ecs_tree_size_ipv4 = 0;
+		else cfg_parser->cfg->max_ecs_tree_size_ipv4 = (uint32_t)atoi($2);
+	#else
+		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+	#endif
+		free($2);
+	}
+	;
+server_max_ecs_tree_size_ipv6: VAR_MAX_ECS_TREE_SIZE_IPV6 STRING_ARG
+	{
+	#ifdef CLIENT_SUBNET
+		OUTYY(("P(max_ecs_tree_size_ipv6:%s)\n", $2));
+		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+			yyerror("IPv6 ECS tree size expected");
+		else if (atoi($2) < 0)
+			cfg_parser->cfg->max_ecs_tree_size_ipv6 = 0;
+		else cfg_parser->cfg->max_ecs_tree_size_ipv6 = (uint32_t)atoi($2);
+	#else
+		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
+	#endif
+		free($2);
+	}
+	;
 server_interface: VAR_INTERFACE STRING_ARG
 	{
 		OUTYY(("P(server_interface:%s)\n", $2));
@@ -747,6 +916,28 @@
 			yyerror("out of memory");
 	}
 	;
+server_tls_ciphers: VAR_TLS_CIPHERS STRING_ARG
+	{
+		OUTYY(("P(server_tls_ciphers:%s)\n", $2));
+		free(cfg_parser->cfg->tls_ciphers);
+		cfg_parser->cfg->tls_ciphers = $2;
+	}
+	;
+server_tls_ciphersuites: VAR_TLS_CIPHERSUITES STRING_ARG
+	{
+		OUTYY(("P(server_tls_ciphersuites:%s)\n", $2));
+		free(cfg_parser->cfg->tls_ciphersuites);
+		cfg_parser->cfg->tls_ciphersuites = $2;
+	}
+	;
+server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG
+	{
+		OUTYY(("P(server_tls_session_ticket_keys:%s)\n", $2));
+		if(!cfg_strlist_append(&cfg_parser->cfg->tls_session_ticket_keys,
+			$2))
+			yyerror("out of memory");
+	}
+	;
 server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
 	{
 		OUTYY(("P(server_use_systemd:%s)\n", $2));
@@ -806,6 +997,15 @@
   	free($2);
   }
   ;
+server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG
+  {
+  	OUTYY(("P(server_log_tag_queryreply:%s)\n", $2));
+  	if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+  		yyerror("expected yes or no.");
+  	else cfg_parser->cfg->log_tag_queryreply = (strcmp($2, "yes")==0);
+  	free($2);
+  }
+  ;
 server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG
 	{
 		OUTYY(("P(server_log_servfail:%s)\n", $2));
@@ -1047,6 +1247,14 @@
         free($2);
     }
     ;
+server_stream_wait_size: VAR_STREAM_WAIT_SIZE STRING_ARG
+	{
+		OUTYY(("P(server_stream_wait_size:%s)\n", $2));
+		if(!cfg_parse_memsize($2, &cfg_parser->cfg->stream_wait_size))
+			yyerror("memory size expected");
+		free($2);
+	}
+	;
 server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG
 	{
 		OUTYY(("P(server_edns_buffer_size:%s)\n", $2));
@@ -1342,6 +1550,15 @@
 		free($2);
 	}
 	;
+server_deny_any: VAR_DENY_ANY STRING_ARG
+	{
+		OUTYY(("P(server_deny_any:%s)\n", $2));
+		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+			yyerror("expected yes or no.");
+		else cfg_parser->cfg->deny_any = (strcmp($2, "yes")==0);
+		free($2);
+	}
+	;
 server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
 	{
 		OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
@@ -1380,6 +1597,8 @@
 			yyerror("expected deny, refuse, deny_non_local, "
 				"refuse_non_local, allow, allow_setrd or "
 				"allow_snoop in access control action");
+			free($2);
+			free($3);
 		} else {
 			if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
 				fatal_exit("out of memory adding acl");
@@ -1540,12 +1759,30 @@
 		free($2);
 	}
 	;
+server_serve_expired_reply_ttl: VAR_SERVE_EXPIRED_REPLY_TTL STRING_ARG
+	{
+		OUTYY(("P(server_serve_expired_reply_ttl:%s)\n", $2));
+		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+			yyerror("number expected");
+		else cfg_parser->cfg->serve_expired_reply_ttl = atoi($2);
+		free($2);
+	}
+	;
+server_serve_expired_client_timeout: VAR_SERVE_EXPIRED_CLIENT_TIMEOUT STRING_ARG
+	{
+		OUTYY(("P(server_serve_expired_client_timeout:%s)\n", $2));
+		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+			yyerror("number expected");
+		else cfg_parser->cfg->serve_expired_client_timeout = atoi($2);
+		free($2);
+	}
+	;
 server_fake_dsa: VAR_FAKE_DSA STRING_ARG
 	{
 		OUTYY(("P(server_fake_dsa:%s)\n", $2));
 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
 			yyerror("expected yes or no.");
-#ifdef HAVE_SSL
+#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
 		else fake_dsa = (strcmp($2, "yes")==0);
 		if(fake_dsa)
 			log_warn("test option fake_dsa is enabled");
@@ -1558,7 +1795,7 @@
 		OUTYY(("P(server_fake_sha1:%s)\n", $2));
 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
 			yyerror("expected yes or no.");
-#ifdef HAVE_SSL
+#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
 		else fake_sha1 = (strcmp($2, "yes")==0);
 		if(fake_sha1)
 			log_warn("test option fake_sha1 is enabled");
@@ -1658,17 +1895,29 @@
 		   && strcmp($3, "always_refuse")!=0
 		   && strcmp($3, "always_nxdomain")!=0
 		   && strcmp($3, "noview")!=0
-		   && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
+		   && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0
+		   && strcmp($3, "inform_redirect") != 0
+			 && strcmp($3, "ipset") != 0) {
 			yyerror("local-zone type: expected static, deny, "
 				"refuse, redirect, transparent, "
 				"typetransparent, inform, inform_deny, "
-				"always_transparent, always_refuse, "
-				"always_nxdomain, noview or nodefault");
-		else if(strcmp($3, "nodefault")==0) {
+				"inform_redirect, always_transparent, "
+				"always_refuse, always_nxdomain, noview "
+				", nodefault or ipset");
+			free($2);
+			free($3);
+		} else if(strcmp($3, "nodefault")==0) {
 			if(!cfg_strlist_insert(&cfg_parser->cfg->
 				local_zones_nodefault, $2))
 				fatal_exit("out of memory adding local-zone");
 			free($3);
+#ifdef USE_IPSET
+		} else if(strcmp($3, "ipset")==0) {
+			if(!cfg_strlist_insert(&cfg_parser->cfg->
+				local_zones_ipset, $2))
+				fatal_exit("out of memory adding local-zone");
+			free($3);
+#endif
 		} else {
 			if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones, 
 				$2, $3))
@@ -1718,6 +1967,13 @@
 		free($2);
 	}
 	;
+server_unknown_server_time_limit: VAR_UNKNOWN_SERVER_TIME_LIMIT STRING_ARG
+	{
+		OUTYY(("P(server_unknown_server_time_limit:%s)\n", $2));
+		cfg_parser->cfg->unknown_server_time_limit = atoi($2);
+		free($2);
+	}
+	;
 server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG
 	{
 		OUTYY(("P(server_max_udp_size:%s)\n", $2));
@@ -1770,8 +2026,10 @@
 			&len);
 		free($3);
 		OUTYY(("P(server_local_zone_tag:%s)\n", $2));
-		if(!bitlist)
+		if(!bitlist) {
 			yyerror("could not parse tags, (define-tag them first)");
+			free($2);
+		}
 		if(bitlist) {
 			if(!cfg_strbytelist_insert(
 				&cfg_parser->cfg->local_zone_tags,
@@ -1789,8 +2047,10 @@
 			&len);
 		free($3);
 		OUTYY(("P(server_access_control_tag:%s)\n", $2));
-		if(!bitlist)
+		if(!bitlist) {
 			yyerror("could not parse tags, (define-tag them first)");
+			free($2);
+		}
 		if(bitlist) {
 			if(!cfg_strbytelist_insert(
 				&cfg_parser->cfg->acl_tags,
@@ -1843,8 +2103,6 @@
 		if(!cfg_str2list_insert(&cfg_parser->cfg->acl_view,
 			$2, $3)) {
 			yyerror("out of memory");
-			free($2);
-			free($3);
 		}
 	}
 	;
@@ -1855,8 +2113,10 @@
 			&len);
 		free($3);
 		OUTYY(("P(response_ip_tag:%s)\n", $2));
-		if(!bitlist)
+		if(!bitlist) {
 			yyerror("could not parse tags, (define-tag them first)");
+			free($2);
+		}
 		if(bitlist) {
 			if(!cfg_strbytelist_insert(
 				&cfg_parser->cfg->respip_tags,
@@ -1933,6 +2193,8 @@
 		OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", $2, $3));
 		if(atoi($3) == 0 && strcmp($3, "0") != 0) {
 			yyerror("number expected");
+			free($2);
+			free($3);
 		} else {
 			if(!cfg_str2list_insert(&cfg_parser->cfg->
 				ratelimit_for_domain, $2, $3))
@@ -1946,6 +2208,8 @@
 		OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", $2, $3));
 		if(atoi($3) == 0 && strcmp($3, "0") != 0) {
 			yyerror("number expected");
+			free($2);
+			free($3);
 		} else {
 			if(!cfg_str2list_insert(&cfg_parser->cfg->
 				ratelimit_below_domain, $2, $3))
@@ -1974,19 +2238,25 @@
 	;
 server_low_rtt: VAR_LOW_RTT STRING_ARG 
 	{ 
-		OUTYY(("P(server_low_rtt:%s)\n", $2)); 
-		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+		OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n"));
+		free($2);
+	}
+	;
+server_fast_server_num: VAR_FAST_SERVER_NUM STRING_ARG 
+	{ 
+		OUTYY(("P(server_fast_server_num:%s)\n", $2)); 
+		if(atoi($2) <= 0)
 			yyerror("number expected");
-		else cfg_parser->cfg->low_rtt = atoi($2);
+		else cfg_parser->cfg->fast_server_num = atoi($2);
 		free($2);
 	}
 	;
-server_low_rtt_permil: VAR_LOW_RTT_PERMIL STRING_ARG 
+server_fast_server_permil: VAR_FAST_SERVER_PERMIL STRING_ARG 
 	{ 
-		OUTYY(("P(server_low_rtt_permil:%s)\n", $2)); 
+		OUTYY(("P(server_fast_server_permil:%s)\n", $2)); 
 		if(atoi($2) == 0 && strcmp($2, "0") != 0)
 			yyerror("number expected");
-		else cfg_parser->cfg->low_rtt_permil = atoi($2);
+		else cfg_parser->cfg->fast_server_permil = atoi($2);
 		free($2);
 	}
 	;
@@ -2017,10 +2287,10 @@
 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->ipsecmod_enabled = (strcmp($2, "yes")==0);
-		free($2);
 	#else
 		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
 	#endif
+		free($2);
 	}
 	;
 server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG
@@ -2030,10 +2300,10 @@
 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->ipsecmod_ignore_bogus = (strcmp($2, "yes")==0);
-		free($2);
 	#else
 		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
 	#endif
+		free($2);
 	}
 	;
 server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG
@@ -2044,6 +2314,7 @@
 		cfg_parser->cfg->ipsecmod_hook = $2;
 	#else
 		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+		free($2);
 	#endif
 	}
 	;
@@ -2057,6 +2328,7 @@
 		free($2);
 	#else
 		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+		free($2);
 	#endif
 	}
 	;
@@ -2068,6 +2340,7 @@
 			yyerror("out of memory");
 	#else
 		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+		free($2);
 	#endif
 	}
 	;
@@ -2081,6 +2354,7 @@
 		free($2);
 	#else
 		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+		free($2);
 	#endif
 	}
 	;
@@ -2288,17 +2562,26 @@
 		   && strcmp($3, "always_refuse")!=0
 		   && strcmp($3, "always_nxdomain")!=0
 		   && strcmp($3, "noview")!=0
-		   && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0)
+		   && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) {
 			yyerror("local-zone type: expected static, deny, "
 				"refuse, redirect, transparent, "
 				"typetransparent, inform, inform_deny, "
 				"always_transparent, always_refuse, "
 				"always_nxdomain, noview or nodefault");
-		else if(strcmp($3, "nodefault")==0) {
+			free($2);
+			free($3);
+		} else if(strcmp($3, "nodefault")==0) {
 			if(!cfg_strlist_insert(&cfg_parser->cfg->views->
 				local_zones_nodefault, $2))
 				fatal_exit("out of memory adding local-zone");
 			free($3);
+#ifdef USE_IPSET
+		} else if(strcmp($3, "ipset")==0) {
+			if(!cfg_strlist_insert(&cfg_parser->cfg->views->
+				local_zones_ipset, $2))
+				fatal_exit("out of memory adding local-zone");
+			free($3);
+#endif
 		} else {
 			if(!cfg_str2list_insert(
 				&cfg_parser->cfg->views->local_zones, 
@@ -2330,7 +2613,6 @@
 		OUTYY(("P(view_local_data:%s)\n", $2));
 		if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, $2)) {
 			fatal_exit("out of memory adding local-data");
-			free($2);
 		}
 	}
 	;
@@ -2453,6 +2735,7 @@
 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap = (strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG
@@ -2468,6 +2751,7 @@
 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_send_identity = (strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG
@@ -2476,6 +2760,7 @@
 		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_send_version = (strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG
@@ -2499,6 +2784,7 @@
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_log_resolver_query_messages =
 			(strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG
@@ -2508,6 +2794,7 @@
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_log_resolver_response_messages =
 			(strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG
@@ -2517,6 +2804,7 @@
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_log_client_query_messages =
 			(strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG
@@ -2526,6 +2814,7 @@
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_log_client_response_messages =
 			(strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG
@@ -2535,6 +2824,7 @@
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_log_forwarder_query_messages =
 			(strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG
@@ -2544,6 +2834,7 @@
 			yyerror("expected yes or no.");
 		else cfg_parser->cfg->dnstap_log_forwarder_response_messages =
 			(strcmp($2, "yes")==0);
+		free($2);
 	}
 	;
 pythonstart: VAR_PYTHON
@@ -2558,8 +2849,8 @@
 py_script: VAR_PYTHON_SCRIPT STRING_ARG
 	{
 		OUTYY(("P(python-script:%s)\n", $2));
-		free(cfg_parser->cfg->python_script);
-		cfg_parser->cfg->python_script = $2;
+		if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, $2))
+			yyerror("out of memory");
 	}
 server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
 	{
@@ -2590,15 +2881,14 @@
 server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG
 	{
 		OUTYY(("P(server_response_ip_data:%s)\n", $2));
-			if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
-				$2, $3))
-				fatal_exit("out of memory adding response-ip-data");
+		if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
+			$2, $3))
+			fatal_exit("out of memory adding response-ip-data");
 	}
 	;
 dnscstart: VAR_DNSCRYPT
 	{
 		OUTYY(("\nP(dnscrypt:)\n"));
-		OUTYY(("\nP(dnscrypt:)\n"));
 	}
 	;
 contents_dnsc: contents_dnsc content_dnsc
@@ -2625,7 +2915,6 @@
 dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG
 	{
 		OUTYY(("P(dnsc_dnscrypt_port:%s)\n", $2));
-
 		if(atoi($2) == 0)
 			yyerror("port number expected");
 		else cfg_parser->cfg->dnscrypt_port = atoi($2);
@@ -2720,13 +3009,11 @@
 	{
 	#ifdef USE_CACHEDB
 		OUTYY(("P(backend:%s)\n", $2));
-		if(cfg_parser->cfg->cachedb_backend)
-			yyerror("cachedb backend override, there must be one "
-				"backend");
 		free(cfg_parser->cfg->cachedb_backend);
 		cfg_parser->cfg->cachedb_backend = $2;
 	#else
 		OUTYY(("P(Compiled without cachedb, ignoring)\n"));
+		free($2);
 	#endif
 	}
 	;
@@ -2734,9 +3021,6 @@
 	{
 	#ifdef USE_CACHEDB
 		OUTYY(("P(secret-seed:%s)\n", $2));
-		if(cfg_parser->cfg->cachedb_secret)
-			yyerror("cachedb secret-seed override, there must be "
-				"only one secret");
 		free(cfg_parser->cfg->cachedb_secret);
 		cfg_parser->cfg->cachedb_secret = $2;
 	#else
@@ -2796,6 +3080,45 @@
 		}
 	}
 	;
+	ipsetstart: VAR_IPSET
+		{
+			OUTYY(("\nP(ipset:)\n"));
+		}
+		;
+	contents_ipset: contents_ipset content_ipset
+		| ;
+	content_ipset: ipset_name_v4 | ipset_name_v6
+		;
+	ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG
+		{
+		#ifdef USE_IPSET
+			OUTYY(("P(name-v4:%s)\n", $2));
+			if(cfg_parser->cfg->ipset_name_v4)
+				yyerror("ipset name v4 override, there must be one "
+					"name for ip v4");
+			free(cfg_parser->cfg->ipset_name_v4);
+			cfg_parser->cfg->ipset_name_v4 = $2;
+		#else
+			OUTYY(("P(Compiled without ipset, ignoring)\n"));
+			free($2);
+		#endif
+		}
+	;
+	ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG
+	{
+		#ifdef USE_IPSET
+			OUTYY(("P(name-v6:%s)\n", $2));
+			if(cfg_parser->cfg->ipset_name_v6)
+				yyerror("ipset name v6 override, there must be one "
+					"name for ip v6");
+			free(cfg_parser->cfg->ipset_name_v6);
+			cfg_parser->cfg->ipset_name_v6 = $2;
+		#else
+			OUTYY(("P(Compiled without ipset, ignoring)\n"));
+			free($2);
+		#endif
+		}
+	;
 %%
 
 /* parse helper routines could be here */
@@ -2815,3 +3138,5 @@
 			"always_refuse or always_nxdomain");
 	}
 }
+
+
--- contrib/unbound/util/data/dname.c.orig
+++ contrib/unbound/util/data/dname.c
@@ -75,6 +75,8 @@
 {
 	size_t len = 0;
 	size_t labellen;
+	if(maxlen == 0)
+		return 0; /* too short, shortest is '0' root label */
 	labellen = *dname++;
 	while(labellen) {
 		if(labellen&0xc0)
@@ -231,6 +233,7 @@
 dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
 {
 	uint8_t len1, len2;
+	int count1 = 0, count2 = 0;
 	log_assert(pkt && d1 && d2);
 	len1 = *d1++;
 	len2 = *d2++;
@@ -237,11 +240,21 @@
 	while( len1 != 0 || len2 != 0 ) {
 		/* resolve ptrs */
 		if(LABEL_IS_PTR(len1)) {
+			if((size_t)PTR_OFFSET(len1, *d1)
+				>= sldns_buffer_limit(pkt))
+				return -1;
+			if(count1++ > MAX_COMPRESS_PTRS)
+				return -1;
 			d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1));
 			len1 = *d1++;
 			continue;
 		}
 		if(LABEL_IS_PTR(len2)) {
+			if((size_t)PTR_OFFSET(len2, *d2)
+				>= sldns_buffer_limit(pkt))
+				return 1;
+			if(count2++ > MAX_COMPRESS_PTRS)
+				return 1;
 			d2 = sldns_buffer_at(pkt, PTR_OFFSET(len2, *d2));
 			len2 = *d2++;
 			continue;
@@ -300,6 +313,7 @@
 	uint8_t labuf[LDNS_MAX_LABELLEN+1];
 	uint8_t lablen;
 	int i;
+	int count = 0;
 
 	/* preserve case of query, make hash label by label */
 	lablen = *dname++;
@@ -306,6 +320,11 @@
 	while(lablen) {
 		if(LABEL_IS_PTR(lablen)) {
 			/* follow pointer */
+			if((size_t)PTR_OFFSET(lablen, *dname)
+				>= sldns_buffer_limit(pkt))
+				return h;
+			if(count++ > MAX_COMPRESS_PTRS)
+				return h;
 			dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
 			lablen = *dname++;
 			continue;
@@ -327,16 +346,29 @@
 void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname)
 {
 	/* copy over the dname and decompress it at the same time */
+	size_t comprcount = 0;
 	size_t len = 0;
 	uint8_t lablen;
 	lablen = *dname++;
 	while(lablen) {
 		if(LABEL_IS_PTR(lablen)) {
+			if(comprcount++ > MAX_COMPRESS_PTRS) {
+				/* too many compression pointers */
+				*to = 0; /* end the result prematurely */
+				return;
+			}
 			/* follow pointer */
+			if((size_t)PTR_OFFSET(lablen, *dname)
+				>= sldns_buffer_limit(pkt))
+				return;
 			dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
 			lablen = *dname++;
 			continue;
 		}
+		if(lablen > LDNS_MAX_LABELLEN) {
+			*to = 0; /* end the result prematurely */
+			return;
+		}
 		log_assert(lablen <= LDNS_MAX_LABELLEN);
 		len += (size_t)lablen+1;
 		if(len >= LDNS_MAX_DOMAINLEN) {
@@ -357,6 +389,7 @@
 void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname)
 {
 	uint8_t lablen;
+	int count = 0;
 	if(!out) out = stdout;
 	if(!dname) return;
 
@@ -370,6 +403,15 @@
 				fputs("??compressionptr??", out);
 				return;
 			}
+			if((size_t)PTR_OFFSET(lablen, *dname)
+				>= sldns_buffer_limit(pkt)) {
+				fputs("??compressionptr??", out);
+				return;
+			}
+			if(count++ > MAX_COMPRESS_PTRS) {
+				fputs("??compressionptr??", out);
+				return;
+			}
 			dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
 			lablen = *dname++;
 			continue;
@@ -546,6 +588,34 @@
 	return 1;
 }
 
+int
+dname_has_label(uint8_t* dname, size_t dnamelen, uint8_t* label)
+{
+	size_t len;
+
+	/* 1 byte needed for the label length */
+	if(dnamelen < 1)
+		return 0;
+
+	len = *dname;
+	while(len <= dnamelen) {
+		if(!(*dname)) {
+			if(*dname == *label)
+				return 1; /* empty label match */
+			/* termination label found, stop iterating */
+			return 0;
+		}
+		if(*dname == *label && *label &&
+			memlowercmp(dname+1, label+1, *dname) == 0)
+			return 1;
+		len += *dname;
+		dname += *dname;
+		dname++;
+		len++;
+	}
+	return 0;
+}
+
 int 
 dname_buffer_write(sldns_buffer* pkt, uint8_t* dname)
 {
--- contrib/unbound/util/data/dname.h.orig
+++ contrib/unbound/util/data/dname.h
@@ -197,6 +197,15 @@
 int dname_lab_startswith(uint8_t* label, char* prefix, char** endptr);
 
 /**
+ * Check if dname contains label
+ * @param dname: dname
+ * @param dnamelen: length of dname
+ * @param label: label to be checked for presence in dname
+ * @return: 1 if dname has this label, 0 otherwise
+ */
+int dname_has_label(uint8_t* dname, size_t dnamelen, uint8_t* label);
+
+/**
  * See if domain name d1 is a strict subdomain of d2.
  * That is a subdomain, but not equal. 
  * @param d1: domain name, uncompressed wireformat
--- contrib/unbound/util/data/msgencode.c.orig
+++ contrib/unbound/util/data/msgencode.c
@@ -50,6 +50,11 @@
 #include "sldns/sbuffer.h"
 #include "services/localzone.h"
 
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#include <sys/time.h>
+
 /** return code that means the function ran out of memory. negative so it does
  * not conflict with DNS rcodes. */
 #define RETVAL_OUTMEM	-2
@@ -475,7 +480,8 @@
 			sldns_buffer_write(pkt, &key->rk.type, 2);
 			sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
 			if(data->rr_ttl[j] < timenow)
-				sldns_buffer_write_u32(pkt, 0);
+				sldns_buffer_write_u32(pkt,
+					SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0);
 			else 	sldns_buffer_write_u32(pkt, 
 					data->rr_ttl[j]-timenow);
 			if(c) {
@@ -512,7 +518,8 @@
 			sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_RRSIG);
 			sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
 			if(data->rr_ttl[i] < timenow)
-				sldns_buffer_write_u32(pkt, 0);
+				sldns_buffer_write_u32(pkt,
+					SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0);
 			else 	sldns_buffer_write_u32(pkt, 
 					data->rr_ttl[i]-timenow);
 			/* rrsig rdata cannot be compressed, perform 100+ byte
@@ -634,15 +641,37 @@
 	return 0;
 }
 
-int 
-reply_info_encode(struct query_info* qinfo, struct reply_info* rep, 
-	uint16_t id, uint16_t flags, sldns_buffer* buffer, time_t timenow, 
-	struct regional* region, uint16_t udpsize, int dnssec)
+static int
+negative_answer(struct reply_info* rep) {
+	size_t i;
+	int ns_seen = 0;
+	if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN)
+		return 1;
+	if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR &&
+		rep->an_numrrsets != 0)
+		return 0; /* positive */
+	if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR &&
+		FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN)
+		return 0;
+	for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++){
+		if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_SOA)
+			return 1;
+		if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS)
+			ns_seen = 1;
+	}
+	if(ns_seen) return 0; /* could be referral, NS, but no SOA */
+	return 1;
+}
+
+int
+reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
+	uint16_t id, uint16_t flags, sldns_buffer* buffer, time_t timenow,
+	struct regional* region, uint16_t udpsize, int dnssec, int minimise)
 {
 	uint16_t ancount=0, nscount=0, arcount=0;
 	struct compress_tree_node* tree = 0;
 	int r;
-	size_t rr_offset; 
+	size_t rr_offset;
 
 	sldns_buffer_clear(buffer);
 	if(udpsize < sldns_buffer_limit(buffer))
@@ -658,7 +687,7 @@
 
 	/* insert query section */
 	if(rep->qdcount) {
-		if((r=insert_query(qinfo, &tree, buffer, region)) != 
+		if((r=insert_query(qinfo, &tree, buffer, region)) !=
 			RETVAL_OK) {
 			if(r == RETVAL_TRUNC) {
 				/* create truncated message */
@@ -672,7 +701,7 @@
 	}
 	/* roundrobin offset. using query id for random number.  With ntohs
 	 * for different roundrobins for sequential id client senders. */
-	rr_offset = RRSET_ROUNDROBIN?ntohs(id):0;
+	rr_offset = RRSET_ROUNDROBIN?ntohs(id)+(timenow?timenow:time(NULL)):0;
 
 	/* "prepend" any local alias records in the answer section if this
 	 * response is supposed to be authoritative.  Currently it should
@@ -702,8 +731,8 @@
 	}
 
 	/* insert answer section */
-	if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer, 
-		0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype, 
+	if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
+		0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
 		dnssec, rr_offset)) != RETVAL_OK) {
 		if(r == RETVAL_TRUNC) {
 			/* create truncated message */
@@ -717,9 +746,9 @@
 	sldns_buffer_write_u16_at(buffer, 6, ancount);
 
 	/* if response is positive answer, auth/add sections are not required */
-	if( ! (MINIMAL_RESPONSES && positive_answer(rep, qinfo->qtype)) ) {
+	if( ! (minimise && positive_answer(rep, qinfo->qtype)) ) {
 		/* insert auth section */
-		if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer, 
+		if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
 			rep->an_numrrsets, timenow, region, &tree,
 			LDNS_SECTION_AUTHORITY, qinfo->qtype,
 			dnssec, rr_offset)) != RETVAL_OK) {
@@ -734,20 +763,22 @@
 		}
 		sldns_buffer_write_u16_at(buffer, 8, nscount);
 
-		/* insert add section */
-		if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer, 
-			rep->an_numrrsets + rep->ns_numrrsets, timenow, region, 
-			&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype, 
-			dnssec, rr_offset)) != RETVAL_OK) {
-			if(r == RETVAL_TRUNC) {
-				/* no need to set TC bit, this is the additional */
-				sldns_buffer_write_u16_at(buffer, 10, arcount);
-				sldns_buffer_flip(buffer);
-				return 1;
+		if(! (minimise && negative_answer(rep))) {
+			/* insert add section */
+			if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
+				rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
+				&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
+				dnssec, rr_offset)) != RETVAL_OK) {
+				if(r == RETVAL_TRUNC) {
+					/* no need to set TC bit, this is the additional */
+					sldns_buffer_write_u16_at(buffer, 10, arcount);
+					sldns_buffer_flip(buffer);
+					return 1;
+				}
+				return 0;
 			}
-			return 0;
+			sldns_buffer_write_u16_at(buffer, 10, arcount);
 		}
-		sldns_buffer_write_u16_at(buffer, 10, arcount);
 	}
 	sldns_buffer_flip(buffer);
 	return 1;
@@ -758,7 +789,7 @@
 {
 	size_t rdatalen = 0;
 	struct edns_option* opt;
-	if(!edns || !edns->edns_present) 
+	if(!edns || !edns->edns_present)
 		return 0;
 	for(opt = edns->opt_list; opt; opt = opt->next) {
 		rdatalen += 4 + opt->opt_len;
@@ -845,7 +876,7 @@
 	}
 
 	if(!reply_info_encode(qinf, rep, id, flags, pkt, timenow, region,
-		udpsize, dnssec)) {
+		udpsize, dnssec, MINIMAL_RESPONSES)) {
 		log_err("reply encode: out of memory");
 		return 0;
 	}
--- contrib/unbound/util/data/msgencode.h.orig
+++ contrib/unbound/util/data/msgencode.h
@@ -85,12 +85,14 @@
  * @param region: to store temporary data in.
  * @param udpsize: size of the answer, 512, from EDNS, or 64k for TCP.
  * @param dnssec: if 0 DNSSEC records are omitted from the answer.
+ * @param minimise: if true, the answer is a minimal response, with
+ *   authority and additional removed if possible.
  * @return: nonzero is success, or 
  *	0 on error: malloc failure (no log_err has been done).
  */
 int reply_info_encode(struct query_info* qinfo, struct reply_info* rep, 
 	uint16_t id, uint16_t flags, struct sldns_buffer* buffer, time_t timenow, 
-	struct regional* region, uint16_t udpsize, int dnssec);
+	struct regional* region, uint16_t udpsize, int dnssec, int minimise);
 
 /**
  * Encode query packet. Assumes the buffer is large enough.
--- contrib/unbound/util/data/msgparse.c.orig
+++ contrib/unbound/util/data/msgparse.c
@@ -55,7 +55,11 @@
 {
 	if(LABEL_IS_PTR(*dnow)) {
 		/* ptr points to a previous dname */
-		uint8_t* p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1]));
+		uint8_t* p;
+		if((size_t)PTR_OFFSET(dnow[0], dnow[1])
+			>= sldns_buffer_limit(pkt))
+			return -1;
+		p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1]));
 		if( p == dprfirst || p == dprlast )
 			return 0;
 		/* prev dname is also a ptr, both ptrs are the same. */
@@ -1061,11 +1065,12 @@
 	size_t rdata_len;
 	uint8_t* rdata_ptr;
 	log_assert(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) == 1);
+	memset(edns, 0, sizeof(*edns));
 	if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 ||
 		LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) {
 		if(!skip_pkt_rrs(pkt, ((int)LDNS_ANCOUNT(sldns_buffer_begin(pkt)))+
 			((int)LDNS_NSCOUNT(sldns_buffer_begin(pkt)))))
-			return 0;
+			return LDNS_RCODE_FORMERR;
 	}
 	/* check edns section is present */
 	if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
@@ -1072,7 +1077,6 @@
 		return LDNS_RCODE_FORMERR;
 	}
 	if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) == 0) {
-		memset(edns, 0, sizeof(*edns));
 		edns->udp_size = 512;
 		return 0;
 	}
--- contrib/unbound/util/data/msgparse.h.orig
+++ contrib/unbound/util/data/msgparse.h
@@ -79,8 +79,12 @@
 extern time_t MIN_TTL;
 /** Maximum Negative TTL that is allowed */
 extern time_t MAX_NEG_TTL;
+/** If we serve expired entries and prefetch them */
+extern int SERVE_EXPIRED;
 /** Time to serve records after expiration */
 extern time_t SERVE_EXPIRED_TTL;
+/** TTL to use for expired records */
+extern time_t SERVE_EXPIRED_REPLY_TTL;
 /** Negative cache time (for entries without any RRs.) */
 #define NORR_TTL 5 /* seconds */
 
--- contrib/unbound/util/data/msgreply.c.orig
+++ contrib/unbound/util/data/msgreply.c
@@ -61,8 +61,12 @@
 time_t MIN_TTL = 0;
 /** MAX Negative TTL, for SOA records in authority section */
 time_t MAX_NEG_TTL = 3600; /* one hour */
+/** If we serve expired entries and prefetch them */
+int SERVE_EXPIRED = 0;
 /** Time to serve records after expiration */
 time_t SERVE_EXPIRED_TTL = 0;
+/** TTL to use for expired records */
+time_t SERVE_EXPIRED_REPLY_TTL = 30;
 
 /** allocate qinfo, return 0 on error */
 static int
@@ -195,6 +199,8 @@
 	}
 	if(*rr_ttl < MIN_TTL)
 		*rr_ttl = MIN_TTL;
+	if(*rr_ttl > MAX_TTL)
+		*rr_ttl = MAX_TTL;
 	if(*rr_ttl < data->ttl)
 		data->ttl = *rr_ttl;
 
@@ -241,10 +247,10 @@
 				break;
 			}
 			if(len) {
+				log_assert(len <= pkt_len);
 				memmove(to, sldns_buffer_current(pkt), len);
 				to += len;
 				sldns_buffer_skip(pkt, (ssize_t)len);
-				log_assert(len <= pkt_len);
 				pkt_len -= len;
 			}
 			rdf++;
@@ -817,7 +823,7 @@
 	sldns_buffer* buf = sldns_buffer_new(65535);
 	struct regional* region = regional_create();
 	if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0, 
-		region, 65535, 1)) {
+		region, 65535, 1, 0)) {
 		log_info("%s: log_dns_msg: out of memory", str);
 	} else {
 		char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf),
@@ -853,7 +859,9 @@
 	addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf));
 	if(rcode == LDNS_RCODE_FORMERR)
 	{
-		log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
+		if(LOG_TAG_QUERYREPLY)
+			log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf);
+		else	log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
 	} else {
 		if(qinf->qname)
 			dname_str(qinf->qname, qname_buf);
@@ -861,9 +869,13 @@
 		pktlen = sldns_buffer_limit(rmsg);
 		sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf));
 		sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf));
-		log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+		if(LOG_TAG_QUERYREPLY)
+		     log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
 			clientip_buf, qname_buf, type_buf, class_buf,
 			rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
+		else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+			clientip_buf, qname_buf, type_buf, class_buf,
+			rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
 	}
 }
 
--- contrib/unbound/util/data/msgreply.h.orig
+++ contrib/unbound/util/data/msgreply.h
@@ -157,7 +157,7 @@
 	time_t prefetch_ttl;
 
 	/** 
-	 * Reply TTL extended with serve exipred TTL, to limit time to serve
+	 * Reply TTL extended with serve expired TTL, to limit time to serve
 	 * expired message.
 	 */
 	time_t serve_expired_ttl;
--- contrib/unbound/util/data/packed_rrset.c.orig
+++ contrib/unbound/util/data/packed_rrset.c
@@ -40,6 +40,7 @@
  */
 
 #include "config.h"
+#include "util/data/msgparse.h"
 #include "util/data/packed_rrset.h"
 #include "util/data/dname.h"
 #include "util/storage/lookup3.h"
@@ -351,11 +352,11 @@
 	/* make TTLs relative - once per rrset */
 	for(i=0; i<d->count + d->rrsig_count; i++) {
 		if(d->rr_ttl[i] < now)
-			d->rr_ttl[i] = 0;
+			d->rr_ttl[i] = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0;
 		else	d->rr_ttl[i] -= now;
 	}
 	if(d->ttl < now)
-		d->ttl = 0;
+		d->ttl = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0;
 	else	d->ttl -= now;
 	return ck;
 }
@@ -386,3 +387,19 @@
 	packed_rrset_ttl_add(dd, now);
 	return dk;
 }
+
+int
+packed_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
+	size_t* index)
+{
+	size_t i;
+	for(i=0; i<d->count; i++) {
+		if(d->rr_len[i] != len)
+			continue;
+		if(memcmp(d->rr_data[i], rdata, len) == 0) {
+			*index = i;
+			return 1;
+		}
+	}
+	return 0;
+}
--- contrib/unbound/util/data/packed_rrset.h.orig
+++ contrib/unbound/util/data/packed_rrset.h
@@ -446,4 +446,17 @@
 	struct ub_packed_rrset_key* key, struct alloc_cache* alloc, 
 	time_t now);
 
+/**
+ * Find RR index in packed rrset
+ * Raw comparison, does not canonicalize RDATA
+ * @param d: packed rrset
+ * @param rdata: RDATA of RR to find
+ * @param len: length of rdata
+ * @param index: pointer to int to store index of found RR
+ * @return 1 if RR found, 0 otherwise
+ */
+int
+packed_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
+	size_t* index);
+
 #endif /* UTIL_DATA_PACKED_RRSET_H */
--- contrib/unbound/util/edns.c.orig
+++ contrib/unbound/util/edns.c
@@ -40,7 +40,7 @@
  */
 
 #include "config.h"
-
+#include "util/edns.h"
 #include "util/config_file.h"
 #include "util/netevent.h"
 #include "util/regional.h"
--- contrib/unbound/util/fptr_wlist.c.orig
+++ contrib/unbound/util/fptr_wlist.c
@@ -90,6 +90,9 @@
 #ifdef CLIENT_SUBNET
 #include "edns-subnet/subnetmod.h"
 #endif
+#ifdef USE_IPSET
+#include "ipset/ipset.h"
+#endif
 
 int 
 fptr_whitelist_comm_point(comm_point_callback_type *fptr)
@@ -127,6 +130,8 @@
 #endif
 	else if(fptr == &auth_xfer_timer) return 1;
 	else if(fptr == &auth_xfer_probe_timer_callback) return 1;
+	else if(fptr == &auth_xfer_transfer_timer_callback) return 1;
+	else if(fptr == &mesh_serve_expired_callback) return 1;
 	return 0;
 }
 
@@ -303,6 +308,9 @@
 {
 	if(fptr == NULL) return 1;
 	else if(fptr == &rrset_markdel) return 1;
+#ifdef CLIENT_SUBNET
+	else if(fptr == &subnet_markdel) return 1;
+#endif
 	return 0;
 }
 
@@ -354,8 +362,8 @@
 }
 
 int 
-fptr_whitelist_modenv_detect_cycle(int (*fptr)(        
-	struct module_qstate* qstate, struct query_info* qinfo,         
+fptr_whitelist_modenv_detect_cycle(int (*fptr)(
+	struct module_qstate* qstate, struct query_info* qinfo,
 	uint16_t flags, int prime, int valrec))
 {
 	if(fptr == &mesh_detect_cycle) return 1;
@@ -381,6 +389,9 @@
 #ifdef CLIENT_SUBNET
 	else if(fptr == &subnetmod_init) return 1;
 #endif
+#ifdef USE_IPSET
+	else if(fptr == &ipset_init) return 1;
+#endif
 	return 0;
 }
 
@@ -403,6 +414,9 @@
 #ifdef CLIENT_SUBNET
 	else if(fptr == &subnetmod_deinit) return 1;
 #endif
+#ifdef USE_IPSET
+	else if(fptr == &ipset_deinit) return 1;
+#endif
 	return 0;
 }
 
@@ -426,6 +440,9 @@
 #ifdef CLIENT_SUBNET
 	else if(fptr == &subnetmod_operate) return 1;
 #endif
+#ifdef USE_IPSET
+	else if(fptr == &ipset_operate) return 1;
+#endif
 	return 0;
 }
 
@@ -449,6 +466,9 @@
 #ifdef CLIENT_SUBNET
 	else if(fptr == &subnetmod_inform_super) return 1;
 #endif
+#ifdef USE_IPSET
+	else if(fptr == &ipset_inform_super) return 1;
+#endif
 	return 0;
 }
 
@@ -472,6 +492,9 @@
 #ifdef CLIENT_SUBNET
 	else if(fptr == &subnetmod_clear) return 1;
 #endif
+#ifdef USE_IPSET
+	else if(fptr == &ipset_clear) return 1;
+#endif
 	return 0;
 }
 
@@ -494,6 +517,9 @@
 #ifdef CLIENT_SUBNET
 	else if(fptr == &subnetmod_get_mem) return 1;
 #endif
+#ifdef USE_IPSET
+	else if(fptr == &ipset_get_mem) return 1;
+#endif
 	return 0;
 }
 
@@ -561,9 +587,12 @@
 #ifdef CLIENT_SUBNET
 	if(fptr == &ecs_whitelist_check)
 		return 1;
-#else
+#endif
+#ifdef WITH_PYTHONMODULE
+        if(fptr == &python_inplace_cb_query_generic)
+                return 1;
+#endif
 	(void)fptr;
-#endif
 	return 0;
 }
 
@@ -590,3 +619,10 @@
 #endif
 	return 0;
 }
+
+int fptr_whitelist_serve_expired_lookup(serve_expired_lookup_func_type* fptr)
+{
+	if(fptr == &mesh_serve_expired_lookup)
+		return 1;
+	return 0;
+}
--- contrib/unbound/util/fptr_wlist.h.orig
+++ contrib/unbound/util/fptr_wlist.h
@@ -377,6 +377,13 @@
 int fptr_whitelist_inplace_cb_query_response(
 	inplace_cb_query_response_func_type* fptr);
 
+/**
+ * Check function pointer whitelist for serve_expired_lookup func values.
+ * @param fptr: function pointer to check.
+ * @return false if not in whitelist.
+ */
+int fptr_whitelist_serve_expired_lookup(serve_expired_lookup_func_type* fptr);
+
 /** Due to module breakage by fptr wlist, these test app declarations
  * are presented here */
 /** 
--- contrib/unbound/util/iana_ports.inc.orig
+++ contrib/unbound/util/iana_ports.inc
@@ -960,8 +960,6 @@
 1298,
 1299,
 1300,
-1301,
-1302,
 1303,
 1304,
 1305,
@@ -1848,7 +1846,6 @@
 2197,
 2198,
 2199,
-2200,
 2201,
 2202,
 2203,
@@ -3907,6 +3904,7 @@
 4600,
 4601,
 4621,
+4646,
 4658,
 4659,
 4660,
@@ -4768,6 +4766,7 @@
 8088,
 8097,
 8100,
+8111,
 8115,
 8116,
 8118,
@@ -4796,10 +4795,12 @@
 8206,
 8207,
 8208,
+8211,
 8230,
 8231,
 8232,
 8243,
+8266,
 8276,
 8280,
 8282,
@@ -4862,6 +4863,7 @@
 8805,
 8807,
 8808,
+8809,
 8873,
 8880,
 8883,
--- contrib/unbound/util/log.c.orig
+++ contrib/unbound/util/log.c
@@ -61,7 +61,7 @@
 #endif
 
 /* default verbosity */
-enum verbosity_value verbosity = 0;
+enum verbosity_value verbosity = NO_VERBOSE;
 /** the file logged to. */
 static FILE* logfile = 0;
 /** if key has been created */
@@ -70,16 +70,15 @@
 static ub_thread_key_type logkey;
 #ifndef THREADS_DISABLED
 /** pthread mutex to protect FILE* */
-static lock_quick_type log_lock;
+static lock_basic_type log_lock;
 #endif
 /** the identity of this executable/process */
 static const char* ident="unbound";
+static const char* default_ident="unbound";
 #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS)
 /** are we using syslog(3) to log to */
 static int logging_to_syslog = 0;
 #endif /* HAVE_SYSLOG_H */
-/** time to print in log, if NULL, use time(2) */
-static time_t* log_now = NULL;
 /** print time in UTC or in secondsfrom1970 */
 static int log_time_asc = 0;
 
@@ -90,18 +89,18 @@
 	if(!key_created) {
 		key_created = 1;
 		ub_thread_key_create(&logkey, NULL);
-		lock_quick_init(&log_lock);
+		lock_basic_init(&log_lock);
 	}
-	lock_quick_lock(&log_lock);
+	lock_basic_lock(&log_lock);
 	if(logfile 
 #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS)
 	|| logging_to_syslog
 #endif
 	) {
-		lock_quick_unlock(&log_lock); /* verbose() needs the lock */
+		lock_basic_unlock(&log_lock); /* verbose() needs the lock */
 		verbose(VERB_QUERY, "switching log to %s", 
 			use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"));
-		lock_quick_lock(&log_lock);
+		lock_basic_lock(&log_lock);
 	}
 	if(logfile && logfile != stderr) {
 		FILE* cl = logfile;
@@ -117,9 +116,11 @@
 	if(use_syslog) {
 		/* do not delay opening until first write, because we may
 		 * chroot and no longer be able to access dev/log and so on */
-		openlog(ident, LOG_NDELAY, LOG_DAEMON);
+		/* the facility is LOG_DAEMON by default, but
+		 * --with-syslog-facility=LOCAL[0-7] can override it */
+		openlog(ident, LOG_NDELAY, UB_SYSLOG_FACILITY);
 		logging_to_syslog = 1;
-		lock_quick_unlock(&log_lock);
+		lock_basic_unlock(&log_lock);
 		return;
 	}
 #elif defined(UB_ON_WINDOWS)
@@ -128,13 +129,13 @@
 	}
 	if(use_syslog) {
 		logging_to_syslog = 1;
-		lock_quick_unlock(&log_lock);
+		lock_basic_unlock(&log_lock);
 		return;
 	}
 #endif /* HAVE_SYSLOG_H */
 	if(!filename || !filename[0]) {
 		logfile = stderr;
-		lock_quick_unlock(&log_lock);
+		lock_basic_unlock(&log_lock);
 		return;
 	}
 	/* open the file for logging */
@@ -143,7 +144,7 @@
 		filename += strlen(chrootdir);
 	f = fopen(filename, "a");
 	if(!f) {
-		lock_quick_unlock(&log_lock);
+		lock_basic_unlock(&log_lock);
 		log_err("Could not open logfile %s: %s", filename, 
 			strerror(errno));
 		return;
@@ -153,14 +154,14 @@
 	setvbuf(f, NULL, (int)_IOLBF, 0);
 #endif
 	logfile = f;
-	lock_quick_unlock(&log_lock);
+	lock_basic_unlock(&log_lock);
 }
 
 void log_file(FILE *f)
 {
-	lock_quick_lock(&log_lock);
+	lock_basic_lock(&log_lock);
 	logfile = f;
-	lock_quick_unlock(&log_lock);
+	lock_basic_unlock(&log_lock);
 }
 
 void log_thread_set(int* num)
@@ -181,11 +182,24 @@
 	ident = id;
 }
 
-void log_set_time(time_t* t)
+void log_ident_set_default(const char* id)
 {
-	log_now = t;
+	default_ident = id;
 }
 
+void log_ident_revert_to_default()
+{
+	ident = default_ident;
+}
+
+void log_ident_set_or_default(const char* identity)
+{
+	if(identity == NULL || identity[0] == 0)
+		log_ident_set(default_ident);
+	else
+		log_ident_set(identity);
+}
+
 void log_set_time_asc(int use_asc)
 {
 	log_time_asc = use_asc;
@@ -250,14 +264,12 @@
 		return;
 	}
 #endif /* HAVE_SYSLOG_H */
-	lock_quick_lock(&log_lock);
+	lock_basic_lock(&log_lock);
 	if(!logfile) {
-		lock_quick_unlock(&log_lock);
+		lock_basic_unlock(&log_lock);
 		return;
 	}
-	if(log_now)
-		now = (time_t)*log_now;
-	else	now = (time_t)time(NULL);
+	now = (time_t)time(NULL);
 #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R) 
 	if(log_time_asc && strftime(tmbuf, sizeof(tmbuf), "%b %d %H:%M:%S",
 		localtime_r(&now, &tm))%(sizeof(tmbuf)) != 0) {
@@ -279,7 +291,7 @@
 	/* line buffering does not work on windows */
 	fflush(logfile);
 #endif
-	lock_quick_unlock(&log_lock);
+	lock_basic_unlock(&log_lock);
 }
 
 /**
@@ -391,6 +403,24 @@
 	log_hex_f(verbosity, msg, data, length);
 }
 
+void
+log_query(const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	log_vmsg(LOG_INFO, "query", format, args);
+	va_end(args);
+}
+
+void
+log_reply(const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	log_vmsg(LOG_INFO, "reply", format, args);
+	va_end(args);
+}
+
 void log_buf(enum verbosity_value level, const char* msg, sldns_buffer* buf)
 {
 	if(verbosity < level)
--- contrib/unbound/util/log.h.orig
+++ contrib/unbound/util/log.h
@@ -107,19 +107,30 @@
 int log_thread_get(void);
 
 /**
- * Set identity to print, default is 'unbound'. 
+ * Set identity to print, default is 'unbound'.
  * @param id: string to print. Name of executable.
  */
 void log_ident_set(const char* id);
 
 /**
- * Set the time value to print in log entries.
- * @param t: the point is copied and used to find the time.
- * 	if NULL, time(2) is used.
+ * Set default identity to print, default is 'unbound'.
+ * @param id: string to print. Name of executable.
  */
-void log_set_time(time_t* t);
+void log_ident_set_default(const char* id);
 
 /**
+ * Revert identity to print, back to the recorded default value.
+ */
+void log_ident_revert_to_default(void);
+
+/**
+ * Set identity to print if there is an identity, otherwise
+ * set the default.
+ * @param identity: the identity to set.
+ */
+void log_ident_set_or_default(const char* identity);
+
+/**
  * Set if the time value is printed ascii or decimal in log entries.
  * @param use_asc: if true, ascii is printed, otherwise decimal.
  *	If the conversion fails or you have no time functions, 
@@ -161,6 +172,20 @@
 void log_hex(const char* msg, void* data, size_t length);
 
 /**
+ * Log query.
+ * Pass printf formatted arguments. No trailing newline is needed.
+ * @param format: printf-style format string. Arguments follow.
+ */
+void log_query(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
+
+/**
+ * Log reply.
+ * Pass printf formatted arguments. No trailing newline is needed.
+ * @param format: printf-style format string. Arguments follow.
+ */
+void log_reply(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
+
+/**
  * Easy alternative for log_hex, takes a sldns_buffer.
  * @param level: verbosity level for this message, compared to global 
  *	verbosity setting.
--- contrib/unbound/util/mini_event.c.orig
+++ contrib/unbound/util/mini_event.c
@@ -41,6 +41,7 @@
  */
 
 #include "config.h"
+#include "util/mini_event.h"
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
@@ -48,7 +49,6 @@
 
 #if defined(USE_MINI_EVENT) && !defined(USE_WINSOCK)
 #include <signal.h>
-#include "util/mini_event.h"
 #include "util/fptr_wlist.h"
 
 /** compare events in tree, based on timevalue, ptr for uniqueness */
@@ -313,7 +313,7 @@
 		struct timeval *now = ev->ev_base->time_tv;
 		ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec;
 		ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec;
-		while(ev->ev_timeout.tv_usec > 1000000) {
+		while(ev->ev_timeout.tv_usec >= 1000000) {
 			ev->ev_timeout.tv_usec -= 1000000;
 			ev->ev_timeout.tv_sec++;
 		}
--- contrib/unbound/util/module.h.orig
+++ contrib/unbound/util/module.h
@@ -307,6 +307,17 @@
 	struct dns_msg* response, int id, void* cb_args);
 
 /**
+ * Function called when looking for (expired) cached answers during the serve
+ * expired logic.
+ * Called as func(qstate, lookup_qinfo)
+ * Where:
+ *	qstate: the query state.
+ *	lookup_qinfo: the qinfo to lookup for.
+ */
+typedef struct dns_msg* serve_expired_lookup_func_type(
+	struct module_qstate* qstate, struct query_info* lookup_qinfo);
+
+/**
  * Module environment.
  * Services and data provided to the module.
  */
@@ -572,6 +583,14 @@
 struct respip_action_info;
 
 /**
+ * Struct to hold relevant data for serve expired
+ */
+struct serve_expired_data {
+	struct comm_timer* timer;
+	serve_expired_lookup_func_type* get_cached_answer;
+};
+
+/**
  * Module state, per query.
  */
 struct module_qstate {
@@ -612,6 +631,8 @@
 	struct mesh_state* mesh_info;
 	/** how many seconds before expiry is this prefetched (0 if not) */
 	time_t prefetch_leeway;
+	/** serve expired data */
+	struct serve_expired_data* serve_expired_data;
 
 	/** incoming edns options from the front end */
 	struct edns_option* edns_opts_front_in;
--- contrib/unbound/util/net_help.c.orig
+++ contrib/unbound/util/net_help.c
@@ -43,11 +43,14 @@
 #include "util/data/dname.h"
 #include "util/module.h"
 #include "util/regional.h"
+#include "util/config_file.h"
 #include "sldns/parseutil.h"
 #include "sldns/wire2str.h"
 #include <fcntl.h>
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
 #endif
 #ifdef HAVE_OPENSSL_ERR_H
 #include <openssl/err.h>
@@ -67,6 +70,15 @@
 /** rrset order roundrobin: default is no */
 int RRSET_ROUNDROBIN = 0;
 
+/** log tag queries with name instead of 'info' for filtering */
+int LOG_TAG_QUERYREPLY = 0;
+
+static struct tls_session_ticket_key {
+	unsigned char *key_name;
+	unsigned char *aes_key;
+	unsigned char *hmac_key;
+} *ticket_keys;
+
 /* returns true is string addr is an ip6 specced address */
 int
 str_is_ip6(const char* str)
@@ -272,6 +284,113 @@
 	return 1;
 }
 
+/* RPZ format address dname to network byte order address */
+static int ipdnametoaddr(uint8_t* dname, size_t dnamelen,
+	struct sockaddr_storage* addr, socklen_t* addrlen, int* af)
+{
+	uint8_t* ia;
+	size_t dnamelabs = dname_count_labels(dname);
+	uint8_t lablen;
+	char* e = NULL;
+	int z = 0;
+	size_t len = 0;
+	int i;
+	*af = AF_INET;
+
+	/* need 1 byte for label length */
+	if(dnamelen < 1)
+		return 0;
+
+	if(dnamelabs > 6 ||
+		dname_has_label(dname, dnamelen, (uint8_t*)"\002zz")) {
+		*af = AF_INET6;
+	}
+	len = *dname;
+	lablen = *dname++;
+	i = (*af == AF_INET) ? 3 : 15;
+	if(*af == AF_INET6) {
+		struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
+		*addrlen = (socklen_t)sizeof(struct sockaddr_in6);
+		memset(sa, 0, *addrlen);
+		sa->sin6_family = AF_INET6;
+		ia = (uint8_t*)&sa->sin6_addr;
+	} else { /* ip4 */
+		struct sockaddr_in* sa = (struct sockaddr_in*)addr;
+		*addrlen = (socklen_t)sizeof(struct sockaddr_in);
+		memset(sa, 0, *addrlen);
+		sa->sin_family = AF_INET;
+		ia = (uint8_t*)&sa->sin_addr;
+	}
+	while(lablen && i >= 0 && len <= dnamelen) {
+		char buff[LDNS_MAX_LABELLEN+1];
+		uint16_t chunk; /* big enough to not overflow on IPv6 hextet */
+		if((*af == AF_INET && (lablen > 3 || dnamelabs > 6)) ||
+			(*af == AF_INET6 && (lablen > 4 || dnamelabs > 10))) {
+			return 0;
+		}
+		if(memcmp(dname, "zz", 2) == 0 && *af == AF_INET6) {
+			/* Add one or more 0 labels. Address is initialised at
+			 * 0, so just skip the zero part. */
+			int zl = 11 - dnamelabs;
+			if(z || zl < 0)
+				return 0;
+			z = 1;
+			i -= (zl*2);
+		} else {
+			memcpy(buff, dname, lablen);
+			buff[lablen] = '\0';
+			chunk = strtol(buff, &e, (*af == AF_INET) ? 10 : 16);
+			if(!e || *e != '\0' || (*af == AF_INET && chunk > 255))
+				return 0;
+			if(*af == AF_INET) {
+				log_assert(i < 4 && i >= 0);
+				ia[i] = (uint8_t)chunk;
+				i--;
+			} else {
+				log_assert(i < 16 && i >= 1);
+				/* ia in network byte order */
+				ia[i-1] = (uint8_t)(chunk >> 8);
+				ia[i] = (uint8_t)(chunk & 0x00FF);
+				i -= 2;
+			}
+		}
+		dname += lablen;
+		lablen = *dname++;
+		len += lablen;
+	}
+	if(i != -1)
+		/* input too short */
+		return 0;
+	return 1;
+}
+
+int netblockdnametoaddr(uint8_t* dname, size_t dnamelen,
+	struct sockaddr_storage* addr, socklen_t* addrlen, int* net, int* af)
+{
+	char buff[3 /* 3 digit netblock */ + 1];
+	size_t nlablen;
+	if(dnamelen < 1 || *dname > 3)
+		/* netblock invalid */
+		return 0;
+	nlablen = *dname;
+
+	if(dnamelen < 1 + nlablen)
+		return 0;
+
+	memcpy(buff, dname+1, nlablen);
+	buff[nlablen] = '\0';
+	*net = atoi(buff);
+	if(*net == 0 && strcmp(buff, "0") != 0)
+		return 0;
+	dname += nlablen;
+	dname++;
+	if(!ipdnametoaddr(dname, dnamelen-1-nlablen, addr, addrlen, af))
+		return 0;
+	if((*af == AF_INET6 && *net > 128) || (*af == AF_INET && *net > 32))
+		return 0;
+	return 1;
+}
+
 int authextstrtoaddr(char* str, struct sockaddr_storage* addr, 
 	socklen_t* addrlen, char** auth_name)
 {
@@ -361,6 +480,37 @@
 	log_info("%s %s %s %s", str, buf, ts, cs);
 }
 
+void
+log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass)
+{
+	char buf[LDNS_MAX_DOMAINLEN+1];
+	char t[12], c[12];
+	const char *ts, *cs; 
+	dname_str(name, buf);
+	if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG";
+	else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR";
+	else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR";
+	else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB";
+	else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA";
+	else if(type == LDNS_RR_TYPE_ANY) ts = "ANY";
+	else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name)
+		ts = sldns_rr_descript(type)->_name;
+	else {
+		snprintf(t, sizeof(t), "TYPE%d", (int)type);
+		ts = t;
+	}
+	if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) &&
+		sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name)
+		cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name;
+	else {
+		snprintf(c, sizeof(c), "CLASS%d", (int)dclass);
+		cs = c;
+	}
+	if(LOG_TAG_QUERYREPLY)
+		log_query("%s %s %s %s", str, buf, ts, cs);
+	else	log_info("%s %s %s %s", str, buf, ts, cs);
+}
+
 void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, 
 	struct sockaddr_storage* addr, socklen_t addrlen)
 {
@@ -655,10 +805,19 @@
 log_crypto_err(const char* str)
 {
 #ifdef HAVE_SSL
+	log_crypto_err_code(str, ERR_get_error());
+#else
+	(void)str;
+#endif /* HAVE_SSL */
+}
+
+void log_crypto_err_code(const char* str, unsigned long err)
+{
+#ifdef HAVE_SSL
 	/* error:[error code]:[library name]:[function name]:[reason string] */
 	char buf[128];
 	unsigned long e;
-	ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
+	ERR_error_string_n(err, buf, sizeof(buf));
 	log_err("%s crypto %s", str, buf);
 	while( (e=ERR_get_error()) ) {
 		ERR_error_string_n(e, buf, sizeof(buf));
@@ -666,6 +825,7 @@
 	}
 #else
 	(void)str;
+	(void)err;
 #endif /* HAVE_SSL */
 }
 
@@ -675,11 +835,13 @@
 #ifdef HAVE_SSL
 	SSL_CTX* ctx = (SSL_CTX*)ctxt;
 	/* no SSLv2, SSLv3 because has defects */
+#if SSL_OP_NO_SSLv2 != 0
 	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
 		!= SSL_OP_NO_SSLv2){
 		log_crypto_err("could not set SSL_OP_NO_SSLv2");
 		return 0;
 	}
+#endif
 	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
 		!= SSL_OP_NO_SSLv3){
 		log_crypto_err("could not set SSL_OP_NO_SSLv3");
@@ -701,6 +863,14 @@
 		return 0;
 	}
 #endif
+#if defined(SSL_OP_NO_RENEGOTIATION)
+	/* disable client renegotiation */
+	if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
+		SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) {
+		log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION");
+		return 0;
+	}
+#endif
 #if defined(SHA256_DIGEST_LENGTH) && defined(USE_ECDSA)
 	/* if we have sha256, set the cipher list to have no known vulns */
 	if(!SSL_CTX_set_cipher_list(ctx, "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"))
@@ -759,6 +929,16 @@
 		log_crypto_err("could not SSL_CTX_new");
 		return NULL;
 	}
+	if(!key || key[0] == 0) {
+		log_err("error: no tls-service-key file specified");
+		SSL_CTX_free(ctx);
+		return NULL;
+	}
+	if(!pem || pem[0] == 0) {
+		log_err("error: no tls-service-pem file specified");
+		SSL_CTX_free(ctx);
+		return NULL;
+	}
 	if(!listen_sslctx_setup(ctx)) {
 		SSL_CTX_free(ctx);
 		return NULL;
@@ -897,6 +1077,7 @@
 		log_crypto_err("could not allocate SSL_CTX pointer");
 		return NULL;
 	}
+#if SSL_OP_NO_SSLv2 != 0
 	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
 		!= SSL_OP_NO_SSLv2) {
 		log_crypto_err("could not set SSL_OP_NO_SSLv2");
@@ -903,6 +1084,7 @@
 		SSL_CTX_free(ctx);
 		return NULL;
 	}
+#endif
 	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
 		!= SSL_OP_NO_SSLv3) {
 		log_crypto_err("could not set SSL_OP_NO_SSLv3");
@@ -909,6 +1091,14 @@
 		SSL_CTX_free(ctx);
 		return NULL;
 	}
+#if defined(SSL_OP_NO_RENEGOTIATION)
+	/* disable client renegotiation */
+	if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
+		SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) {
+		log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION");
+		return 0;
+	}
+#endif
 	if(key && key[0]) {
 		if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) {
 			log_err("error in client certificate %s", pem);
@@ -966,7 +1156,7 @@
 		return NULL;
 	}
 	SSL_set_accept_state(ssl);
-	(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+	(void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY);
 	if(!SSL_set_fd(ssl, fd)) {
 		log_crypto_err("could not SSL_set_fd");
 		SSL_free(ssl);
@@ -988,7 +1178,7 @@
 		return NULL;
 	}
 	SSL_set_connect_state(ssl);
-	(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+	(void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY);
 	if(!SSL_set_fd(ssl, fd)) {
 		log_crypto_err("could not SSL_set_fd");
 		SSL_free(ssl);
@@ -1006,11 +1196,19 @@
 static lock_basic_type *ub_openssl_locks = NULL;
 
 /** callback that gets thread id for openssl */
+#ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK
+static void
+ub_crypto_id_cb(CRYPTO_THREADID *id)
+{
+	CRYPTO_THREADID_set_numeric(id, (unsigned long)log_thread_get());
+}
+#else
 static unsigned long
 ub_crypto_id_cb(void)
 {
 	return (unsigned long)log_thread_get();
 }
+#endif
 
 static void
 ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
@@ -1035,7 +1233,11 @@
 	for(i=0; i<CRYPTO_num_locks(); i++) {
 		lock_basic_init(&ub_openssl_locks[i]);
 	}
+#  ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK
+	CRYPTO_THREADID_set_callback(&ub_crypto_id_cb);
+#  else
 	CRYPTO_set_id_callback(&ub_crypto_id_cb);
+#  endif
 	CRYPTO_set_locking_callback(&ub_crypto_lock_cb);
 #endif /* OPENSSL_THREADS */
 	return 1;
@@ -1047,7 +1249,11 @@
 	int i;
 	if(!ub_openssl_locks)
 		return;
+#  ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK
+	CRYPTO_THREADID_set_callback(NULL);
+#  else
 	CRYPTO_set_id_callback(NULL);
+#  endif
 	CRYPTO_set_locking_callback(NULL);
 	for(i=0; i<CRYPTO_num_locks(); i++) {
 		lock_basic_destroy(&ub_openssl_locks[i]);
@@ -1056,3 +1262,150 @@
 #endif /* OPENSSL_THREADS */
 }
 
+int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys) {
+#ifdef HAVE_SSL
+	size_t s = 1;
+	struct config_strlist* p;
+	struct tls_session_ticket_key *keys;
+	for(p = tls_session_ticket_keys; p; p = p->next) {
+		s++;
+	}
+	keys = calloc(s, sizeof(struct tls_session_ticket_key));
+	if(!keys)
+		return 0;
+	memset(keys, 0, s*sizeof(*keys));
+	ticket_keys = keys;
+
+	for(p = tls_session_ticket_keys; p; p = p->next) {
+		size_t n;
+		unsigned char *data;
+		FILE *f;
+
+		data = (unsigned char *)malloc(80);
+		if(!data)
+			return 0;
+
+		f = fopen(p->str, "r");
+		if(!f) {
+			log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno));
+			free(data);
+			return 0;
+		}
+		n = fread(data, 1, 80, f);
+		fclose(f);
+
+		if(n != 80) {
+			log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", p->str, (int)n);
+			free(data);
+			return 0;
+		}
+		verbose(VERB_OPS, "read tls-session-ticket-key: %s", p->str);
+
+		keys->key_name = data;
+		keys->aes_key = data + 16;
+		keys->hmac_key = data + 48;
+		keys++;
+	}
+	/* terminate array with NULL key name entry */
+	keys->key_name = NULL;
+	if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) {
+		log_err("no support for TLS session ticket");
+		return 0;
+	}
+	return 1;
+#else
+	(void)sslctx;
+	(void)tls_session_ticket_keys;
+	return 0;
+#endif
+
+}
+
+int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name, unsigned char* iv, void *evp_sctx, void *hmac_ctx, int enc)
+{
+#ifdef HAVE_SSL
+	const EVP_MD *digest;
+	const EVP_CIPHER *cipher;
+	int evp_cipher_length;
+	digest = EVP_sha256();
+	cipher = EVP_aes_256_cbc();
+	evp_cipher_length = EVP_CIPHER_iv_length(cipher);
+	if( enc == 1 ) {
+		/* encrypt */
+		verbose(VERB_CLIENT, "start session encrypt");
+		memcpy(key_name, ticket_keys->key_name, 16);
+		if (RAND_bytes(iv, evp_cipher_length) != 1) {
+			verbose(VERB_CLIENT, "RAND_bytes failed");
+			return -1;
+		}
+		if (EVP_EncryptInit_ex(evp_sctx, cipher, NULL, ticket_keys->aes_key, iv) != 1) {
+			verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed");
+			return -1;
+		}
+#ifndef HMAC_INIT_EX_RETURNS_VOID
+		if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) {
+			verbose(VERB_CLIENT, "HMAC_Init_ex failed");
+			return -1;
+		}
+#else
+		HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL);
+#endif
+		return 1;
+	} else if (enc == 0) {
+		/* decrypt */
+		struct tls_session_ticket_key *key;
+		verbose(VERB_CLIENT, "start session decrypt");
+		for(key = ticket_keys; key->key_name != NULL; key++) {
+			if (!memcmp(key_name, key->key_name, 16)) {
+				verbose(VERB_CLIENT, "Found session_key");
+				break;
+			}
+		}
+		if(key->key_name == NULL) {
+			verbose(VERB_CLIENT, "Not found session_key");
+			return 0;
+		}
+
+#ifndef HMAC_INIT_EX_RETURNS_VOID
+		if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) {
+			verbose(VERB_CLIENT, "HMAC_Init_ex failed");
+			return -1;
+		}
+#else
+		HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL);
+#endif
+		if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) {
+			log_err("EVP_DecryptInit_ex failed");
+			return -1;
+		}
+
+		return (key == ticket_keys) ? 1 : 2;
+	}
+	return -1;
+#else
+	(void)key_name;
+	(void)iv;
+	(void)evp_sctx;
+	(void)hmac_ctx;
+	(void)enc;
+	return 0;
+#endif
+}
+
+void
+listen_sslctx_delete_ticket_keys(void)
+{
+	struct tls_session_ticket_key *key;
+	if(!ticket_keys) return;
+	for(key = ticket_keys; key->key_name != NULL; key++) {
+		/* wipe key data from memory*/
+#ifdef HAVE_EXPLICIT_BZERO
+		explicit_bzero(key->key_name, 80);
+#else
+		memset(key->key_name, 0xdd, 80);
+#endif
+		free(key->key_name);
+	}
+	free(ticket_keys);
+	ticket_keys = NULL;
+}
--- contrib/unbound/util/net_help.h.orig
+++ contrib/unbound/util/net_help.h
@@ -44,6 +44,7 @@
 #include "util/log.h"
 struct sock_list;
 struct regional;
+struct config_strlist;
 
 /** DNS constants for uint16_t style flag manipulation. host byteorder. 
  *                                1  1  1  1  1  1
@@ -99,6 +100,9 @@
 /** rrset order roundrobin */
 extern int RRSET_ROUNDROBIN;
 
+/** log tag queries with name instead of 'info' for filtering */
+extern int LOG_TAG_QUERYREPLY;
+
 /**
  * See if string is ip4 or ip6.
  * @param str: IP specification.
@@ -236,6 +240,12 @@
 	uint8_t* name, uint16_t type, uint16_t dclass);
 
 /**
+ * Like log_nametypeclass, but logs with log_query for query logging
+ */
+void log_query_in(const char* str, uint8_t* name, uint16_t type,
+	uint16_t dclass);
+
+/**
  * Compare two sockaddrs. Imposes an ordering on the addresses.
  * Compares address and port.
  * @param addr1: address 1.
@@ -369,6 +379,13 @@
 void log_crypto_err(const char* str);
 
 /**
+ * Log libcrypto error from errcode with descriptive string, calls log_err.
+ * @param str: what failed.
+ * @param err: error code from ERR_get_error.
+ */
+void log_crypto_err_code(const char* str, unsigned long err);
+
+/**
  * Set SSL_OP_NOxxx options on SSL context to disable bad crypto
  * @param ctxt: SSL_CTX*
  * @return false on failure.
@@ -428,4 +445,45 @@
  */
 void ub_openssl_lock_delete(void);
 
+/**
+ * setup TLS session ticket
+ * @param sslctx: the SSL_CTX to use (from connect_sslctx_create())
+ * @param tls_session_ticket_keys: TLS ticket secret filenames
+ * @return false on failure (alloc failure).
+ */
+int listen_sslctx_setup_ticket_keys(void* sslctx,
+	struct config_strlist* tls_session_ticket_keys);
+
+/**
+ * callback TLS session ticket encrypt and decrypt
+ * For use with SSL_CTX_set_tlsext_ticket_key_cb
+ * @param s: the SSL_CTX to use (from connect_sslctx_create())
+ * @param key_name: secret name, 16 bytes
+ * @param iv: up to EVP_MAX_IV_LENGTH.
+ * @param evp_ctx: the evp cipher context, function sets this.
+ * @param hmac_ctx: the hmax context, function sets this.
+ * @param enc: 1 is encrypt, 0 is decrypt
+ * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket
+ * 	(the ticket is decrypt only). and <0 for failures.
+ */
+int tls_session_ticket_key_cb(void *s, unsigned char* key_name,unsigned char* iv, void *evp_ctx, void *hmac_ctx, int enc);
+
+/** Free memory used for TLS session ticket keys */
+void listen_sslctx_delete_ticket_keys(void);
+
+/**
+ * RPZ format netblock to network byte order address and netblock
+ * example RPZ netblock format dnames:
+ *  - 24.10.100.51.198.rpz-ip -> 198.51.100.10/24
+ *  - 32.10.zz.db8.2001.rpz-ip -> 2001:db8:0:0:0:0:0:10/32
+ * @param dname: the dname containing RPZ format netblock
+ * @param dnamelen: length of dname
+ * @param addr: where to store sockaddr.
+ * @param addrlen: length of stored sockaddr is returned.
+ * @param net: where to store netmask
+ * @param af: where to store address family.
+ * @return 0 on error.
+ */
+int netblockdnametoaddr(uint8_t* dname, size_t dnamelen,
+	struct sockaddr_storage* addr, socklen_t* addrlen, int* net, int* af);
 #endif /* NET_HELP_H */
--- contrib/unbound/util/netevent.c.orig
+++ contrib/unbound/util/netevent.c
@@ -50,6 +50,7 @@
 #include "sldns/str2wire.h"
 #include "dnstap/dnstap.h"
 #include "dnscrypt/dnscrypt.h"
+#include "services/listen_dnsport.h"
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
 #endif
@@ -150,7 +151,8 @@
 /** create a tcp handler with a parent */
 static struct comm_point* comm_point_create_tcp_handler(
 	struct comm_base *base, struct comm_point* parent, size_t bufsize,
-        comm_point_callback_type* callback, void* callback_arg);
+	struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+	void* callback_arg);
 
 /* -------- End of local definitions -------- */
 
@@ -176,7 +178,7 @@
 	}
 	ub_comm_base_now(b);
 	ub_get_event_sys(b->eb->base, &evnm, &evsys, &evmethod);
-	verbose(VERB_ALGO, "%s %s user %s method.", evnm, evsys, evmethod);
+	verbose(VERB_ALGO, "%s %s uses %s method.", evnm, evsys, evmethod);
 	return b;
 }
 
@@ -924,6 +926,14 @@
 	}
 	/* accept incoming connection. */
 	c_hdl = c->tcp_free;
+	/* clear leftover flags from previous use, and then set the
+	 * correct event base for the event structure for libevent */
+	ub_event_free(c_hdl->ev->ev);
+	c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1, UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT, comm_point_tcp_handle_callback, c_hdl);
+	if(!c_hdl->ev->ev) {
+		log_warn("could not ub_event_new, dropped tcp");
+		return;
+	}
 	log_assert(fd != -1);
 	(void)fd;
 	new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.addr,
@@ -987,8 +997,12 @@
 		c->tcp_is_reading = 1;
 	c->tcp_byte_count = 0;
 	/* switch from listening(write) to listening(read) */
-	comm_point_stop_listening(c);
-	comm_point_start_listening(c, -1, -1);
+	if(c->tcp_req_info) {
+		tcp_req_info_handle_writedone(c->tcp_req_info);
+	} else {
+		comm_point_stop_listening(c);
+		comm_point_start_listening(c, -1, c->tcp_timeout_msec);
+	}
 }
 
 /** do the callback when reading is done */
@@ -1000,11 +1014,15 @@
 	if(c->tcp_do_toggle_rw)
 		c->tcp_is_reading = 0;
 	c->tcp_byte_count = 0;
-	if(c->type == comm_tcp)
-		comm_point_stop_listening(c);
-	fptr_ok(fptr_whitelist_comm_point(c->callback));
-	if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
-		comm_point_start_listening(c, -1, c->tcp_timeout_msec);
+	if(c->tcp_req_info) {
+		tcp_req_info_handle_readdone(c->tcp_req_info);
+	} else {
+		if(c->type == comm_tcp)
+			comm_point_stop_listening(c);
+		fptr_ok(fptr_whitelist_comm_point(c->callback));
+		if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
+			comm_point_start_listening(c, -1, c->tcp_timeout_msec);
+		}
 	}
 }
 
@@ -1034,6 +1052,35 @@
 }
 #endif /* HAVE_SSL */
 
+#ifdef HAVE_SSL
+/** true if the ssl handshake error has to be squelched from the logs */
+static int
+squelch_err_ssl_handshake(unsigned long err)
+{
+	if(verbosity >= VERB_QUERY)
+		return 0; /* only squelch on low verbosity */
+	/* this is very specific, we could filter on ERR_GET_REASON()
+	 * (the third element in ERR_PACK) */
+	if(err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTPS_PROXY_REQUEST) ||
+		err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTP_REQUEST) ||
+		err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER) ||
+		err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_READ_BYTES, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE)
+#ifdef SSL_F_TLS_POST_PROCESS_CLIENT_HELLO
+		|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER)
+#endif
+#ifdef SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO
+		|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL)
+		|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL)
+#  ifdef SSL_R_VERSION_TOO_LOW
+		|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_VERSION_TOO_LOW)
+#  endif
+#endif
+		)
+		return 1;
+	return 0;
+}
+#endif /* HAVE_SSL */
+
 /** continue ssl handshake */
 #ifdef HAVE_SSL
 static int
@@ -1073,14 +1120,25 @@
 			return 0; /* closed */
 		} else if(want == SSL_ERROR_SYSCALL) {
 			/* SYSCALL and errno==0 means closed uncleanly */
+#ifdef EPIPE
+			if(errno == EPIPE && verbosity < 2)
+				return 0; /* silence 'broken pipe' */
+#endif
+#ifdef ECONNRESET
+			if(errno == ECONNRESET && verbosity < 2)
+				return 0; /* silence reset by peer */
+#endif
 			if(errno != 0)
 				log_err("SSL_handshake syscall: %s",
 					strerror(errno));
 			return 0;
 		} else {
-			log_crypto_err("ssl handshake failed");
-			log_addr(1, "ssl handshake failed", &c->repinfo.addr,
-				c->repinfo.addrlen);
+			unsigned long err = ERR_get_error();
+			if(!squelch_err_ssl_handshake(err)) {
+				log_crypto_err_code("ssl handshake failed", err);
+				log_addr(VERB_OPS, "ssl handshake failed", &c->repinfo.addr,
+					c->repinfo.addrlen);
+			}
 			return 0;
 		}
 	}
@@ -1163,6 +1221,8 @@
 			c->tcp_byte_count))) <= 0) {
 			int want = SSL_get_error(c->ssl, r);
 			if(want == SSL_ERROR_ZERO_RETURN) {
+				if(c->tcp_req_info)
+					return tcp_req_info_handle_read_close(c->tcp_req_info);
 				return 0; /* shutdown, closed */
 			} else if(want == SSL_ERROR_WANT_READ) {
 				ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
@@ -1172,6 +1232,10 @@
 				comm_point_listen_for_rw(c, 0, 1);
 				return 1;
 			} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef ECONNRESET
+				if(errno == ECONNRESET && verbosity < 2)
+					return 0; /* silence reset by peer */
+#endif
 				if(errno != 0)
 					log_err("SSL_read syscall: %s",
 						strerror(errno));
@@ -1205,6 +1269,8 @@
 		if(r <= 0) {
 			int want = SSL_get_error(c->ssl, r);
 			if(want == SSL_ERROR_ZERO_RETURN) {
+				if(c->tcp_req_info)
+					return tcp_req_info_handle_read_close(c->tcp_req_info);
 				return 0; /* shutdown, closed */
 			} else if(want == SSL_ERROR_WANT_READ) {
 				ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
@@ -1214,6 +1280,10 @@
 				comm_point_listen_for_rw(c, 0, 1);
 				return 1;
 			} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef ECONNRESET
+				if(errno == ECONNRESET && verbosity < 2)
+					return 0; /* silence reset by peer */
+#endif
 				if(errno != 0)
 					log_err("SSL_read syscall: %s",
 						strerror(errno));
@@ -1247,7 +1317,7 @@
 			return 1;
 	}
 	/* ignore return, if fails we may simply block */
-	(void)SSL_set_mode(c->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+	(void)SSL_set_mode(c->ssl, (long)SSL_MODE_ENABLE_PARTIAL_WRITE);
 	if(c->tcp_byte_count < sizeof(uint16_t)) {
 		uint16_t len = htons(sldns_buffer_limit(c->buffer));
 		ERR_clear_error();
@@ -1274,7 +1344,7 @@
 			if(want == SSL_ERROR_ZERO_RETURN) {
 				return 0; /* closed */
 			} else if(want == SSL_ERROR_WANT_READ) {
-				c->ssl_shake_state = comm_ssl_shake_read;
+				c->ssl_shake_state = comm_ssl_shake_hs_read;
 				comm_point_listen_for_rw(c, 1, 0);
 				return 1; /* wait for read condition */
 			} else if(want == SSL_ERROR_WANT_WRITE) {
@@ -1281,6 +1351,10 @@
 				ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
 				return 1; /* write more later */
 			} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef EPIPE
+				if(errno == EPIPE && verbosity < 2)
+					return 0; /* silence 'broken pipe' */
+#endif
 				if(errno != 0)
 					log_err("SSL_write syscall: %s",
 						strerror(errno));
@@ -1308,7 +1382,7 @@
 		if(want == SSL_ERROR_ZERO_RETURN) {
 			return 0; /* closed */
 		} else if(want == SSL_ERROR_WANT_READ) {
-			c->ssl_shake_state = comm_ssl_shake_read;
+			c->ssl_shake_state = comm_ssl_shake_hs_read;
 			comm_point_listen_for_rw(c, 1, 0);
 			return 1; /* wait for read condition */
 		} else if(want == SSL_ERROR_WANT_WRITE) {
@@ -1315,6 +1389,10 @@
 			ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
 			return 1; /* write more later */
 		} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef EPIPE
+			if(errno == EPIPE && verbosity < 2)
+				return 0; /* silence 'broken pipe' */
+#endif
 			if(errno != 0)
 				log_err("SSL_write syscall: %s",
 					strerror(errno));
@@ -1365,9 +1443,11 @@
 		/* read length bytes */
 		r = recv(fd,(void*)sldns_buffer_at(c->buffer,c->tcp_byte_count),
 			sizeof(uint16_t)-c->tcp_byte_count, 0);
-		if(r == 0)
+		if(r == 0) {
+			if(c->tcp_req_info)
+				return tcp_req_info_handle_read_close(c->tcp_req_info);
 			return 0;
-		else if(r == -1) {
+		} else if(r == -1) {
 #ifndef USE_WINSOCK
 			if(errno == EINTR || errno == EAGAIN)
 				return 1;
@@ -1416,6 +1496,8 @@
 	r = recv(fd, (void*)sldns_buffer_current(c->buffer), 
 		sldns_buffer_remaining(c->buffer), 0);
 	if(r == 0) {
+		if(c->tcp_req_info)
+			return tcp_req_info_handle_read_close(c->tcp_req_info);
 		return 0;
 	} else if(r == -1) {
 #ifndef USE_WINSOCK
@@ -1525,7 +1607,6 @@
 		iov[1].iov_base = sldns_buffer_begin(buffer);
 		iov[1].iov_len = sldns_buffer_limit(buffer);
 		log_assert(iov[0].iov_len > 0);
-		log_assert(iov[1].iov_len > 0);
 		msg.msg_name = &c->repinfo.addr;
 		msg.msg_namelen = c->repinfo.addrlen;
 		msg.msg_iov = iov;
@@ -1592,7 +1673,6 @@
 		iov[1].iov_base = sldns_buffer_begin(buffer);
 		iov[1].iov_len = sldns_buffer_limit(buffer);
 		log_assert(iov[0].iov_len > 0);
-		log_assert(iov[1].iov_len > 0);
 		r = writev(fd, iov, 2);
 #else /* HAVE_WRITEV */
 		r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_byte_count),
@@ -1606,6 +1686,10 @@
   #endif
 			if(errno == EINTR || errno == EAGAIN)
 				return 1;
+#ifdef ECONNRESET
+			if(errno == ECONNRESET && verbosity < 2)
+				return 0; /* silence reset by peer */
+#endif
 #  ifdef HAVE_WRITEV
 			log_err_addr("tcp writev", strerror(errno),
 				&c->repinfo.addr, c->repinfo.addrlen);
@@ -1623,6 +1707,8 @@
 					UB_EV_WRITE);
 				return 1; 
 			}
+			if(WSAGetLastError() == WSAECONNRESET && verbosity < 2)
+				return 0; /* silence reset by peer */
 			log_err_addr("tcp send s",
 				wsa_strerror(WSAGetLastError()),
 				&c->repinfo.addr, c->repinfo.addrlen);
@@ -1646,6 +1732,10 @@
 #ifndef USE_WINSOCK
 		if(errno == EINTR || errno == EAGAIN)
 			return 1;
+#ifdef ECONNRESET
+		if(errno == ECONNRESET && verbosity < 2)
+			return 0; /* silence reset by peer */
+#endif
 		log_err_addr("tcp send r", strerror(errno),
 			&c->repinfo.addr, c->repinfo.addrlen);
 #else
@@ -1655,6 +1745,8 @@
 			ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
 			return 1; 
 		}
+		if(WSAGetLastError() == WSAECONNRESET && verbosity < 2)
+			return 0; /* silence reset by peer */
 		log_err_addr("tcp send r", wsa_strerror(WSAGetLastError()),
 			&c->repinfo.addr, c->repinfo.addrlen);
 #endif
@@ -1669,6 +1761,29 @@
 	return 1;
 }
 
+/** read again to drain buffers when there could be more to read */
+static void
+tcp_req_info_read_again(int fd, struct comm_point* c)
+{
+	while(c->tcp_req_info->read_again) {
+		int r;
+		c->tcp_req_info->read_again = 0;
+		if(c->tcp_is_reading)
+			r = comm_point_tcp_handle_read(fd, c, 0);
+		else 	r = comm_point_tcp_handle_write(fd, c);
+		if(!r) {
+			reclaim_tcp_handler(c);
+			if(!c->tcp_do_close) {
+				fptr_ok(fptr_whitelist_comm_point(
+					c->callback));
+				(void)(*c->callback)(c, c->cb_arg, 
+					NETEVENT_CLOSED, NULL);
+			}
+			return;
+		}
+	}
+}
+
 void 
 comm_point_tcp_handle_callback(int fd, short event, void* arg)
 {
@@ -1697,7 +1812,18 @@
 	}
 #endif
 
+	if(event&UB_EV_TIMEOUT) {
+		verbose(VERB_QUERY, "tcp took too long, dropped");
+		reclaim_tcp_handler(c);
+		if(!c->tcp_do_close) {
+			fptr_ok(fptr_whitelist_comm_point(c->callback));
+			(void)(*c->callback)(c, c->cb_arg,
+				NETEVENT_TIMEOUT, NULL);
+		}
+		return;
+	}
 	if(event&UB_EV_READ) {
+		int has_tcpq = (c->tcp_req_info != NULL);
 		if(!comm_point_tcp_handle_read(fd, c, 0)) {
 			reclaim_tcp_handler(c);
 			if(!c->tcp_do_close) {
@@ -1707,9 +1833,12 @@
 					NETEVENT_CLOSED, NULL);
 			}
 		}
+		if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
+			tcp_req_info_read_again(fd, c);
 		return;
 	}
 	if(event&UB_EV_WRITE) {
+		int has_tcpq = (c->tcp_req_info != NULL);
 		if(!comm_point_tcp_handle_write(fd, c)) {
 			reclaim_tcp_handler(c);
 			if(!c->tcp_do_close) {
@@ -1719,18 +1848,10 @@
 					NETEVENT_CLOSED, NULL);
 			}
 		}
+		if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
+			tcp_req_info_read_again(fd, c);
 		return;
 	}
-	if(event&UB_EV_TIMEOUT) {
-		verbose(VERB_QUERY, "tcp took too long, dropped");
-		reclaim_tcp_handler(c);
-		if(!c->tcp_do_close) {
-			fptr_ok(fptr_whitelist_comm_point(c->callback));
-			(void)(*c->callback)(c, c->cb_arg,
-				NETEVENT_TIMEOUT, NULL);
-		}
-		return;
-	}
 	log_err("Ignored event %d for tcphdl.", event);
 }
 
@@ -1779,6 +1900,10 @@
 			comm_point_listen_for_rw(c, 0, 1);
 			return 1;
 		} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef ECONNRESET
+			if(errno == ECONNRESET && verbosity < 2)
+				return 0; /* silence reset by peer */
+#endif
 			if(errno != 0)
 				log_err("SSL_read syscall: %s",
 					strerror(errno));
@@ -2221,12 +2346,16 @@
 		if(want == SSL_ERROR_ZERO_RETURN) {
 			return 0; /* closed */
 		} else if(want == SSL_ERROR_WANT_READ) {
-			c->ssl_shake_state = comm_ssl_shake_read;
+			c->ssl_shake_state = comm_ssl_shake_hs_read;
 			comm_point_listen_for_rw(c, 1, 0);
 			return 1; /* wait for read condition */
 		} else if(want == SSL_ERROR_WANT_WRITE) {
 			return 1; /* write more later */
 		} else if(want == SSL_ERROR_SYSCALL) {
+#ifdef EPIPE
+			if(errno == EPIPE && verbosity < 2)
+				return 0; /* silence 'broken pipe' */
+#endif
 			if(errno != 0)
 				log_err("SSL_write syscall: %s",
 					strerror(errno));
@@ -2335,6 +2464,16 @@
 	log_assert(c->type == comm_http);
 	ub_comm_base_now(c->ev->base);
 
+	if(event&UB_EV_TIMEOUT) {
+		verbose(VERB_QUERY, "http took too long, dropped");
+		reclaim_http_handler(c);
+		if(!c->tcp_do_close) {
+			fptr_ok(fptr_whitelist_comm_point(c->callback));
+			(void)(*c->callback)(c, c->cb_arg,
+				NETEVENT_TIMEOUT, NULL);
+		}
+		return;
+	}
 	if(event&UB_EV_READ) {
 		if(!comm_point_http_handle_read(fd, c)) {
 			reclaim_http_handler(c);
@@ -2359,16 +2498,6 @@
 		}
 		return;
 	}
-	if(event&UB_EV_TIMEOUT) {
-		verbose(VERB_QUERY, "http took too long, dropped");
-		reclaim_http_handler(c);
-		if(!c->tcp_do_close) {
-			fptr_ok(fptr_whitelist_comm_point(c->callback));
-			(void)(*c->callback)(c, c->cb_arg,
-				NETEVENT_TIMEOUT, NULL);
-		}
-		return;
-	}
 	log_err("Ignored event %d for httphdl.", event);
 }
 
@@ -2523,7 +2652,8 @@
 static struct comm_point* 
 comm_point_create_tcp_handler(struct comm_base *base, 
 	struct comm_point* parent, size_t bufsize,
-        comm_point_callback_type* callback, void* callback_arg)
+	struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+	void* callback_arg)
 {
 	struct comm_point* c = (struct comm_point*)calloc(1,
 		sizeof(struct comm_point));
@@ -2579,6 +2709,20 @@
 	c->repinfo.c = c;
 	c->callback = callback;
 	c->cb_arg = callback_arg;
+	if(spoolbuf) {
+		c->tcp_req_info = tcp_req_info_create(spoolbuf);
+		if(!c->tcp_req_info) {
+			log_err("could not create tcp commpoint");
+			sldns_buffer_free(c->buffer);
+			free(c->timeout);
+			free(c->ev);
+			free(c);
+			return NULL;
+		}
+		c->tcp_req_info->cp = c;
+		c->tcp_do_close = 1;
+		c->tcp_do_toggle_rw = 0;
+	}
 	/* add to parent free list */
 	c->tcp_free = parent->tcp_free;
 	parent->tcp_free = c;
@@ -2590,6 +2734,9 @@
 	{
 		log_err("could not basetset tcphdl event");
 		parent->tcp_free = c->tcp_free;
+		tcp_req_info_delete(c->tcp_req_info);
+		sldns_buffer_free(c->buffer);
+		free(c->timeout);
 		free(c->ev);
 		free(c);
 		return NULL;
@@ -2600,7 +2747,8 @@
 struct comm_point* 
 comm_point_create_tcp(struct comm_base *base, int fd, int num,
 	int idle_timeout, struct tcl_list* tcp_conn_limit, size_t bufsize,
-        comm_point_callback_type* callback, void* callback_arg)
+	struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+	void* callback_arg)
 {
 	struct comm_point* c = (struct comm_point*)calloc(1,
 		sizeof(struct comm_point));
@@ -2667,7 +2815,7 @@
 	/* now prealloc the tcp handlers */
 	for(i=0; i<num; i++) {
 		c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
-			c, bufsize, callback, callback_arg);
+			c, bufsize, spoolbuf, callback, callback_arg);
 		if(!c->tcp_handlers[i]) {
 			comm_point_delete(c);
 			return NULL;
@@ -2949,6 +3097,8 @@
 		}
 	}
 	tcl_close_connection(c->tcl_addr);
+	if(c->tcp_req_info)
+		tcp_req_info_clear(c->tcp_req_info);
 	/* close fd after removing from event lists, or epoll.. is messed up */
 	if(c->fd != -1 && !c->do_not_close) {
 		if(c->type == comm_tcp || c->type == comm_http) {
@@ -2992,6 +3142,9 @@
 			sldns_buffer_free(c->dnscrypt_buffer);
 		}
 #endif
+		if(c->tcp_req_info) {
+			tcp_req_info_delete(c->tcp_req_info);
+		}
 	}
 	ub_event_free(c->ev->ev);
 	free(c->ev);
@@ -3032,8 +3185,12 @@
 			dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
 			&repinfo->addr, repinfo->c->type, repinfo->c->buffer);
 #endif
-		comm_point_start_listening(repinfo->c, -1,
-			repinfo->c->tcp_timeout_msec);
+		if(repinfo->c->tcp_req_info) {
+			tcp_req_info_send_reply(repinfo->c->tcp_req_info);
+		} else {
+			comm_point_start_listening(repinfo->c, -1,
+				repinfo->c->tcp_timeout_msec);
+		}
 	}
 }
 
@@ -3042,10 +3199,12 @@
 {
 	if(!repinfo)
 		return;
-	log_assert(repinfo && repinfo->c);
+	log_assert(repinfo->c);
 	log_assert(repinfo->c->type != comm_tcp_accept);
 	if(repinfo->c->type == comm_udp)
 		return;
+	if(repinfo->c->tcp_req_info)
+		repinfo->c->tcp_req_info->is_drop = 1;
 	reclaim_tcp_handler(repinfo->c);
 }
 
@@ -3061,8 +3220,8 @@
 void 
 comm_point_start_listening(struct comm_point* c, int newfd, int msec)
 {
-	verbose(VERB_ALGO, "comm point start listening %d", 
-		c->fd==-1?newfd:c->fd);
+	verbose(VERB_ALGO, "comm point start listening %d (%d msec)", 
+		c->fd==-1?newfd:c->fd, msec);
 	if(c->type == comm_tcp_accept && !c->tcp_free) {
 		/* no use to start listening no free slots. */
 		return;
--- contrib/unbound/util/netevent.h.orig
+++ contrib/unbound/util/netevent.h
@@ -268,6 +268,9 @@
 	/** the entry for the connection. */
 	struct tcl_addr* tcl_addr;
 
+	/** the structure to keep track of open requests on this channel */
+	struct tcp_req_info* tcp_req_info;
+
 #ifdef USE_MSG_FASTOPEN
 	/** used to track if the sendto() call should be done when using TFO. */
 	int tcp_do_fastopen;
@@ -455,6 +458,8 @@
  * @param idle_timeout: TCP idle timeout in ms.
  * @param tcp_conn_limit: TCP connection limit info.
  * @param bufsize: size of buffer to create for handlers.
+ * @param spoolbuf: shared spool buffer for tcp_req_info structures.
+ * 	or NULL to not create those structures in the tcp handlers.
  * @param callback: callback function pointer for TCP handlers.
  * @param callback_arg: will be passed to your callback function.
  * @return: returns the TCP listener commpoint. You can find the
@@ -464,7 +469,8 @@
  */
 struct comm_point* comm_point_create_tcp(struct comm_base* base,
 	int fd, int num, int idle_timeout, struct tcl_list* tcp_conn_limit,
-	size_t bufsize, comm_point_callback_type* callback, void* callback_arg);
+	size_t bufsize, struct sldns_buffer* spoolbuf,
+	comm_point_callback_type* callback, void* callback_arg);
 
 /**
  * Create an outgoing TCP commpoint. No file descriptor is opened, left at -1.
--- contrib/unbound/util/random.c.orig
+++ contrib/unbound/util/random.c
@@ -78,16 +78,9 @@
  */
 #define MAX_VALUE 0x7fffffff
 
-#if defined(HAVE_SSL)
-void
-ub_systemseed(unsigned int ATTR_UNUSED(seed))
-{
-	/* arc4random_uniform does not need seeds, it gets kernel entropy */
-}
-
+#if defined(HAVE_SSL) || defined(HAVE_LIBBSD)
 struct ub_randstate* 
-ub_initstate(unsigned int ATTR_UNUSED(seed),
-	struct ub_randstate* ATTR_UNUSED(from))
+ub_initstate(struct ub_randstate* ATTR_UNUSED(from))
 {
 	struct ub_randstate* s = (struct ub_randstate*)malloc(1);
 	if(!s) {
@@ -119,13 +112,8 @@
 	int ready;
 };
 
-void ub_systemseed(unsigned int ATTR_UNUSED(seed))
+struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from))
 {
-}
-
-struct ub_randstate* ub_initstate(unsigned int ATTR_UNUSED(seed), 
-	struct ub_randstate* ATTR_UNUSED(from))
-{
 	struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s));
 	if(!s) {
 		log_err("malloc failure in random init");
@@ -140,7 +128,9 @@
 	/* random 31 bit value. */
 	SECStatus s = PK11_GenerateRandom((unsigned char*)&x, (int)sizeof(x));
 	if(s != SECSuccess) {
-		log_err("PK11_GenerateRandom error: %s",
+		/* unbound needs secure randomness for randomized
+		 * ID bits and port numbers in packets to upstream servers */
+		fatal_exit("PK11_GenerateRandom error: %s",
 			PORT_ErrorToString(PORT_GetError()));
 	}
 	return x & MAX_VALUE;
@@ -157,18 +147,8 @@
 	int seeded;
 };
 
-void ub_systemseed(unsigned int ATTR_UNUSED(seed))
+struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from))
 {
-/**
- * We seed on init and not here, as we need the ctx to re-seed.
- * This also means that re-seeding is not supported.
- */
-	log_err("Re-seeding not supported, generator untouched");
-}
-
-struct ub_randstate* ub_initstate(unsigned int seed,
-	struct ub_randstate* ATTR_UNUSED(from))
-{
 	struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s));
 	uint8_t buf[YARROW256_SEED_FILE_SIZE];
 	if(!s) {
@@ -183,15 +163,10 @@
 		yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf);
 		s->seeded = yarrow256_is_seeded(&s->ctx);
 	} else {
-		/* Stretch the uint32 input seed and feed it to Yarrow */
-		uint32_t v = seed;
-		size_t i;
-		for(i=0; i < (YARROW256_SEED_FILE_SIZE/sizeof(seed)); i++) {
-			memmove(buf+i*sizeof(seed), &v, sizeof(seed));
-			v = v*seed + (uint32_t)i;
-		}
-		yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf);
-		s->seeded = yarrow256_is_seeded(&s->ctx);
+		log_err("nettle random(yarrow) cannot initialize, "
+			"getentropy failed: %s", strerror(errno));
+		free(s);
+		return NULL;
 	}
 
 	return s;
@@ -208,10 +183,10 @@
 	}
 	return x & MAX_VALUE;
 }
-#endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */
+#endif /* HAVE_SSL or HAVE_LIBBSD or HAVE_NSS or HAVE_NETTLE */
 
 
-#if defined(HAVE_NSS) || defined(HAVE_NETTLE)
+#if defined(HAVE_NSS) || defined(HAVE_NETTLE) && !defined(HAVE_LIBBSD)
 long int
 ub_random_max(struct ub_randstate* state, long int x)
 {
@@ -223,7 +198,7 @@
 		v = ub_random(state);
 	return (v % x);
 }
-#endif /* HAVE_NSS or HAVE_NETTLE */
+#endif /* HAVE_NSS or HAVE_NETTLE and !HAVE_LIBBSD */
 
 void 
 ub_randfree(struct ub_randstate* s)
--- contrib/unbound/util/random.h.orig
+++ contrib/unbound/util/random.h
@@ -48,24 +48,13 @@
 struct ub_randstate;
 
 /**
- * Initialize the system randomness.  Obtains entropy from the system
- * before a chroot or privilege makes it unavailable. 
- * You do not have to call this, otherwise ub_initstate does so.
- * @param seed: seed value to create state (if no good entropy is found).
- */
-void ub_systemseed(unsigned int seed);
-
-/**
  * Initialize a random generator state for use 
- * @param seed: seed value to create state contents.
- *	(ignored for arc4random).
  * @param from: if not NULL, the seed is taken from this random structure.
  * 	can be used to seed random states via a parent-random-state that
  * 	is itself seeded with entropy.
  * @return new state or NULL alloc failure.
  */
-struct ub_randstate* ub_initstate(unsigned int seed, 
-	struct ub_randstate* from);
+struct ub_randstate* ub_initstate(struct ub_randstate* from);
 
 /**
  * Generate next random number from the state passed along.
--- contrib/unbound/util/regional.c.orig
+++ contrib/unbound/util/regional.c
@@ -84,6 +84,7 @@
 regional_create_custom(size_t size)
 {
 	struct regional* r = (struct regional*)malloc(size);
+	size = ALIGN_UP(size, ALIGNMENT);
 	log_assert(sizeof(struct regional) <= size);
 	if(!r) return NULL;
 	r->first_size = size;
@@ -120,8 +121,18 @@
 void *
 regional_alloc(struct regional *r, size_t size)
 {
-	size_t a = ALIGN_UP(size, ALIGNMENT);
+	size_t a;
 	void *s;
+	if(
+#if SIZEOF_SIZE_T == 8
+		(unsigned long long)size >= 0xffffffffffffff00ULL
+#else
+		(unsigned)size >= (unsigned)0xffffff00UL
+#endif
+		)
+		return NULL; /* protect against integer overflow in
+			malloc and ALIGN_UP */
+	a = ALIGN_UP(size, ALIGNMENT);
 	/* large objects */
 	if(a > REGIONAL_LARGE_OBJECT_SIZE) {
 		s = malloc(ALIGNMENT + size);
--- contrib/unbound/util/shm_side/shm_main.c.orig
+++ contrib/unbound/util/shm_side/shm_main.c
@@ -121,7 +121,7 @@
 		shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL);
 
 	/* SHM: Create the segment */
-	daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0666);
+	daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0644);
 
 	if (daemon->shm_info->id_ctl < 0)
 	{
@@ -134,7 +134,7 @@
 		return 0;
 	}
 
-	daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0666);
+	daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0644);
 
 	if (daemon->shm_info->id_arr < 0)
 	{
@@ -223,8 +223,10 @@
 	struct ub_stats_info *stat_info;
 	int offset;
 
+#ifndef S_SPLINT_S
 	verbose(VERB_DETAIL, "SHM run - worker [%d] - daemon [%p] - timenow(%u) - timeboot(%u)",
 		worker->thread_num, worker->daemon, (unsigned)worker->env.now_tv->tv_sec, (unsigned)worker->daemon->time_boot.tv_sec);
+#endif
 
 	offset = worker->thread_num + 1;
 	stat_total = worker->daemon->shm_info->ptr_arr;
@@ -240,9 +242,11 @@
 		memset(stat_total, 0, sizeof(struct ub_stats_info));
 
 		/* Point to data into SHM */
+#ifndef S_SPLINT_S
 		shm_stat = worker->daemon->shm_info->ptr_ctl;
 		shm_stat->time.now_sec = (long long)worker->env.now_tv->tv_sec;
 		shm_stat->time.now_usec = (long long)worker->env.now_tv->tv_usec;
+#endif
 
 		stat_timeval_subtract(&shm_stat->time.up_sec, &shm_stat->time.up_usec, worker->env.now_tv, &worker->daemon->time_boot);
 		stat_timeval_subtract(&shm_stat->time.elapsed_sec, &shm_stat->time.elapsed_usec, worker->env.now_tv, &worker->daemon->time_last_stat);
--- contrib/unbound/util/storage/dnstree.c.orig
+++ contrib/unbound/util/storage/dnstree.c
@@ -104,11 +104,12 @@
 	return rbtree_insert(tree, &node->node) != NULL;
 }
 
-void addr_tree_init_parents(rbtree_type* tree)
+void addr_tree_init_parents_node(struct addr_tree_node* node)
 {
-        struct addr_tree_node* node, *prev = NULL, *p;
+	struct addr_tree_node* prev = NULL, *p;
         int m;
-        RBTREE_FOR(node, struct addr_tree_node*, tree) {
+	for(; (rbnode_type*)node != RBTREE_NULL;
+		node = (struct addr_tree_node*)rbtree_next((rbnode_type*)node)) {
                 node->parent = NULL;
                 if(!prev || prev->addrlen != node->addrlen) {
                         prev = node;
@@ -130,6 +131,12 @@
         }
 }
 
+void addr_tree_init_parents(rbtree_type* tree)
+{
+	addr_tree_init_parents_node(
+			(struct addr_tree_node*)rbtree_first(tree));
+}
+
 void name_tree_init_parents(rbtree_type* tree)
 {
         struct name_tree_node* node, *prev = NULL, *p;
--- contrib/unbound/util/storage/dnstree.h.orig
+++ contrib/unbound/util/storage/dnstree.h
@@ -174,6 +174,13 @@
 void addr_tree_init_parents(rbtree_type* tree);
 
 /**
+ * Initialize parent pointers in partial addr tree.
+ * Reinitialize pointer for part of tree, used after node deletion
+ * @param node: node to start parent pointer initialization for.
+ */
+void addr_tree_init_parents_node(struct addr_tree_node* node);
+
+/**
  * Lookup closest encloser in addr tree.
  * @param tree: addr tree
  * @param addr: to lookup.
--- contrib/unbound/util/storage/lookup3.c.orig
+++ contrib/unbound/util/storage/lookup3.c
@@ -1,4 +1,7 @@
 /*
+  May 2019(Wouter) patch to enable the valgrind clean implementation all the
+     time.  This enables better security audit and checks, which is better
+     than the speedup.  Git issue #30.  Renamed the define ARRAY_CLEAN_ACCESS.
   February 2013(Wouter) patch defines for BSD endianness, from Brad Smith.
   January 2012(Wouter) added randomised initial value, fallout from 28c3.
   March 2007(Wouter) adapted from lookup3.c original, add config.h include.
@@ -44,6 +47,7 @@
 -------------------------------------------------------------------------------
 */
 /*#define SELF_TEST 1*/
+#define ARRAY_CLEAN_ACCESS 1
 
 #include "config.h"
 #include "util/storage/lookup3.h"
@@ -336,7 +340,7 @@
   u.ptr = key;
   if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
     const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
-#ifdef VALGRIND
+#ifdef ARRAY_CLEAN_ACCESS
     const uint8_t  *k8;
 #endif
 
@@ -361,7 +365,7 @@
      * still catch it and complain.  The masking trick does make the hash
      * noticeably faster for short strings (like English words).
      */
-#ifndef VALGRIND
+#ifndef ARRAY_CLEAN_ACCESS
 
     switch(length)
     {
--- contrib/unbound/util/ub_event.c.orig
+++ contrib/unbound/util/ub_event.c
@@ -295,11 +295,18 @@
 	if (!ev)
 		return NULL;
 
+#ifndef HAVE_EVENT_ASSIGN
 	event_set(ev, fd, NATIVE_BITS(bits), NATIVE_BITS_CB(cb), arg);
 	if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
 		free(ev);
 		return NULL;
 	}
+#else
+	if (event_assign(ev, AS_EVENT_BASE(base), fd, bits, cb, arg) != 0) {
+		free(ev);
+		return NULL;
+	}
+#endif
 	return AS_UB_EVENT(ev);
 }
 
@@ -312,11 +319,18 @@
 	if (!ev)
 		return NULL;
 
+#if !HAVE_DECL_EVSIGNAL_ASSIGN
 	signal_set(ev, fd, NATIVE_BITS_CB(cb), arg);
 	if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
 		free(ev);
 		return NULL;
 	}
+#else
+	if (evsignal_assign(ev, AS_EVENT_BASE(base), fd, cb, arg) != 0) {
+		free(ev);
+		return NULL;
+	}
+#endif
 	return AS_UB_EVENT(ev);
 }
 
@@ -444,7 +458,9 @@
 	if(gettimeofday(tv, NULL) < 0) {
 		log_err("gettimeofday: %s", strerror(errno));
 	}
+#ifndef S_SPLINT_S
 	*tt = tv->tv_sec;
+#endif
 #endif /* USE_MINI_EVENT */
 }
 
--- contrib/unbound/util/ub_event_pluggable.c.orig
+++ contrib/unbound/util/ub_event_pluggable.c
@@ -453,7 +453,7 @@
 	 * ub_base is guaranteed to exist and to be the default
 	 * event base.
 	 */
-	assert(b);
+	assert(b != NULL);
 	*n = "pluggable-event";
 	*s = event_get_version();
 #  if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
@@ -687,6 +687,8 @@
 	if(gettimeofday(tv, NULL) < 0) {
 		log_err("gettimeofday: %s", strerror(errno));
 	}
+#ifndef S_SPLINT_S
 	*tt = tv->tv_sec;
+#endif
 }
 
--- contrib/unbound/util/winsock_event.c.orig
+++ contrib/unbound/util/winsock_event.c
@@ -558,7 +558,7 @@
                 struct timeval *now = ev->ev_base->time_tv;
                 ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec;
                 ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec;
-                while(ev->ev_timeout.tv_usec > 1000000) {
+                while(ev->ev_timeout.tv_usec >= 1000000) {
                         ev->ev_timeout.tv_usec -= 1000000;
                         ev->ev_timeout.tv_sec++;
                 }
--- contrib/unbound/validator/autotrust.c.orig
+++ contrib/unbound/validator/autotrust.c
@@ -86,7 +86,6 @@
 	if(!global)
 		return;
 	/* elements deleted by parent */
-	memset(global, 0, sizeof(*global));
 	free(global);
 }
 
@@ -370,10 +369,10 @@
 		free(tp);
 		return NULL;
 	}
-	lock_basic_unlock(&anchors->lock);
 	lock_basic_init(&tp->lock);
 	lock_protect(&tp->lock, tp, sizeof(*tp));
 	lock_protect(&tp->lock, tp->autr, sizeof(*tp->autr));
+	lock_basic_unlock(&anchors->lock);
 	return tp;
 }
 
@@ -1175,6 +1174,9 @@
 {
 	FILE* out;
 	char* fname = tp->autr->file;
+#ifndef S_SPLINT_S
+	long long llvalue;
+#endif
 	char tempf[2048];
 	log_assert(tp->autr);
 	if(!env) {
@@ -1181,9 +1183,23 @@
 		log_err("autr_write_file: Module environment is NULL.");
 		return;
 	}
-	/* unique name with pid number and thread number */
-	snprintf(tempf, sizeof(tempf), "%s.%d-%d", fname, (int)getpid(),
-		env->worker?*(int*)env->worker:0);
+	/* unique name with pid number, thread number, and struct pointer
+	 * (the pointer uniquifies for multiple libunbound contexts) */
+#ifndef S_SPLINT_S
+#if defined(SIZE_MAX) && defined(UINT32_MAX) && (UINT32_MAX == SIZE_MAX || INT32_MAX == SIZE_MAX)
+	/* avoid warning about upcast on 32bit systems */
+	llvalue = (unsigned long)tp;
+#else
+	llvalue = (unsigned long long)tp;
+#endif
+#ifndef USE_WINSOCK
+	snprintf(tempf, sizeof(tempf), "%s.%d-%d-%llx", fname, (int)getpid(),
+		env->worker?*(int*)env->worker:0, llvalue);
+#else
+	snprintf(tempf, sizeof(tempf), "%s.%d-%d-%I64x", fname, (int)getpid(),
+		env->worker?*(int*)env->worker:0, llvalue);
+#endif
+#endif /* S_SPLINT_S */
 	verbose(VERB_ALGO, "autotrust: write to disk: %s", tempf);
 	out = fopen(tempf, "w");
 	if(!out) {
@@ -2245,7 +2261,7 @@
 		log_info("out of memory in debug_print_ta");
 		return;
 	}
-	if(str && str[0]) str[strlen(str)-1]=0; /* remove newline */
+	if(str[0]) str[strlen(str)-1]=0; /* remove newline */
 	ctime_r(&ta->last_change, buf);
 	if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */
 	log_info("[%s] %s ;;state:%d ;;pending_count:%d%s%s last:%s",
@@ -2267,10 +2283,10 @@
 	log_info("assembled %d DS and %d DNSKEYs", 
 		(int)tp->numDS, (int)tp->numDNSKEY);
 	if(tp->ds_rrset) {
-		log_packed_rrset(0, "DS:", tp->ds_rrset);
+		log_packed_rrset(NO_VERBOSE, "DS:", tp->ds_rrset);
 	}
 	if(tp->dnskey_rrset) {
-		log_packed_rrset(0, "DNSKEY:", tp->dnskey_rrset);
+		log_packed_rrset(NO_VERBOSE, "DNSKEY:", tp->dnskey_rrset);
 	}
 	log_info("file %s", tp->autr->file);
 	ctime_r(&tp->autr->last_queried, buf);
--- contrib/unbound/validator/val_anchor.c.orig
+++ contrib/unbound/validator/val_anchor.c
@@ -1007,12 +1007,12 @@
 		nods = anchors_ds_unsupported(ta);
 		nokey = anchors_dnskey_unsupported(ta);
 		if(nods) {
-			log_nametypeclass(0, "warning: unsupported "
+			log_nametypeclass(NO_VERBOSE, "warning: unsupported "
 				"algorithm for trust anchor", 
 				ta->name, LDNS_RR_TYPE_DS, ta->dclass);
 		}
 		if(nokey) {
-			log_nametypeclass(0, "warning: unsupported "
+			log_nametypeclass(NO_VERBOSE, "warning: unsupported "
 				"algorithm for trust anchor", 
 				ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
 		}
--- contrib/unbound/validator/val_neg.c.orig
+++ contrib/unbound/validator/val_neg.c
@@ -235,6 +235,7 @@
 
 	/* remove it from the lru list */
 	neg_lru_remove(neg, el);
+	log_assert(neg->first != el && neg->last != el);
 	
 	/* go up the tree and reduce counts */
 	p = el;
--- contrib/unbound/validator/val_secalgo.c.orig
+++ contrib/unbound/validator/val_secalgo.c
@@ -54,6 +54,11 @@
 #error "Need crypto library to do digital signature cryptography"
 #endif
 
+/** fake DSA support for unit tests */
+int fake_dsa = 0;
+/** fake SHA1 support for unit tests */
+int fake_sha1 = 0;
+
 /* OpenSSL implementation */
 #ifdef HAVE_SSL
 #ifdef HAVE_OPENSSL_ERR_H
@@ -72,11 +77,6 @@
 #include <openssl/engine.h>
 #endif
 
-/** fake DSA support for unit tests */
-int fake_dsa = 0;
-/** fake SHA1 support for unit tests */
-int fake_sha1 = 0;
-
 /**
  * Output a libcrypto openssl error to the logfile.
  * @param str: string to add to it.
@@ -326,8 +326,10 @@
 #ifdef HAVE_DSA_SIG_SET0
 	if(!DSA_SIG_set0(dsasig, R, S)) return 0;
 #else
+#  ifndef S_SPLINT_S
 	dsasig->r = R;
 	dsasig->s = S;
+#  endif /* S_SPLINT_S */
 #endif
 	*sig = NULL;
 	newlen = i2d_DSA_SIG(dsasig, sig);
@@ -1507,13 +1509,21 @@
 {
 	/* uses libnettle */
 	switch(id) {
-#if defined(USE_DSA) && defined(USE_SHA1)
 	case LDNS_DSA:
 	case LDNS_DSA_NSEC3:
+#if defined(USE_DSA) && defined(USE_SHA1)
+		return 1;
+#else
+		if(fake_dsa || fake_sha1) return 1;
+		return 0;
 #endif
-#ifdef USE_SHA1
 	case LDNS_RSASHA1:
 	case LDNS_RSASHA1_NSEC3:
+#ifdef USE_SHA1
+		return 1;
+#else
+		if(fake_sha1) return 1;
+		return 0;
 #endif
 #ifdef USE_SHA2
 	case LDNS_RSASHA256:
@@ -1725,7 +1735,7 @@
 		{
 			uint8_t digest[SHA256_DIGEST_SIZE];
 			mpz_t x, y;
-			nettle_ecc_point_init(&pubkey, &nettle_secp_256r1);
+			nettle_ecc_point_init(&pubkey, nettle_get_secp_256r1());
 			nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key);
 			nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE);
 			nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock);
@@ -1742,7 +1752,7 @@
 		{
 			uint8_t digest[SHA384_DIGEST_SIZE];
 			mpz_t x, y;
-			nettle_ecc_point_init(&pubkey, &nettle_secp_384r1);
+			nettle_ecc_point_init(&pubkey, nettle_get_secp_384r1());
 			nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key);
 			nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE);
 			nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock);
@@ -1818,6 +1828,15 @@
 		return sec_status_bogus;
 	}
 
+#ifndef USE_DSA
+	if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1))
+		return sec_status_secure;
+#endif
+#ifndef USE_SHA1
+	if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3))
+		return sec_status_secure;
+#endif
+
 	switch(algo) {
 #if defined(USE_DSA) && defined(USE_SHA1)
 	case LDNS_DSA:
--- contrib/unbound/validator/val_sigcrypt.c.orig
+++ contrib/unbound/validator/val_sigcrypt.c
@@ -1225,11 +1225,11 @@
 			(unsigned)incep, (unsigned)now);
 }
 
-/** RFC 1918 comparison, uses unsigned integers, and tries to avoid
+/** RFC 1982 comparison, uses unsigned integers, and tries to avoid
  * compiler optimization (eg. by avoiding a-b<0 comparisons),
  * this routine matches compare_serial(), for SOA serial number checks */
 static int
-compare_1918(uint32_t a, uint32_t b)
+compare_1982(uint32_t a, uint32_t b)
 {
 	/* for 32 bit values */
         const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
@@ -1244,9 +1244,9 @@
 }
 
 /** if we know that b is larger than a, return the difference between them,
- * that is the distance between them. in RFC1918 arith */
+ * that is the distance between them. in RFC1982 arith */
 static uint32_t
-subtract_1918(uint32_t a, uint32_t b)
+subtract_1982(uint32_t a, uint32_t b)
 {
 	/* for 32 bit values */
         const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
@@ -1286,18 +1286,18 @@
 	} else	now = unow;
 
 	/* check them */
-	if(compare_1918(incep, expi) > 0) {
+	if(compare_1982(incep, expi) > 0) {
 		sigdate_error("verify: inception after expiration, "
 			"signature bad", expi, incep, now);
 		*reason = "signature inception after expiration";
 		return 0;
 	}
-	if(compare_1918(incep, now) > 0) {
+	if(compare_1982(incep, now) > 0) {
 		/* within skew ? (calc here to avoid calculation normally) */
-		uint32_t skew = subtract_1918(incep, expi)/10;
+		uint32_t skew = subtract_1982(incep, expi)/10;
 		if(skew < (uint32_t)ve->skew_min) skew = ve->skew_min;
 		if(skew > (uint32_t)ve->skew_max) skew = ve->skew_max;
-		if(subtract_1918(now, incep) > skew) {
+		if(subtract_1982(now, incep) > skew) {
 			sigdate_error("verify: signature bad, current time is"
 				" before inception date", expi, incep, now);
 			*reason = "signature before inception date";
@@ -1306,11 +1306,11 @@
 		sigdate_error("verify warning suspicious signature inception "
 			" or bad local clock", expi, incep, now);
 	}
-	if(compare_1918(now, expi) > 0) {
-		uint32_t skew = subtract_1918(incep, expi)/10;
+	if(compare_1982(now, expi) > 0) {
+		uint32_t skew = subtract_1982(incep, expi)/10;
 		if(skew < (uint32_t)ve->skew_min) skew = ve->skew_min;
 		if(skew > (uint32_t)ve->skew_max) skew = ve->skew_max;
-		if(subtract_1918(expi, now) > skew) {
+		if(subtract_1982(expi, now) > skew) {
 			sigdate_error("verify: signature expired", expi, 
 				incep, now);
 			*reason = "signature expired";
--- contrib/unbound/validator/validator.c.orig
+++ contrib/unbound/validator/validator.c
@@ -121,6 +121,8 @@
 		log_err("out of memory");
 		return 0;
 	}
+	if (env->key_cache)
+		val_env->kcache = env->key_cache;
 	if(!val_env->kcache)
 		val_env->kcache = key_cache_create(cfg);
 	if(!val_env->kcache) {
@@ -146,6 +148,8 @@
 		log_err("validator: cannot apply nsec3 key iterations");
 		return 0;
 	}
+	if (env->neg_cache)
+		val_env->neg_cache = env->neg_cache;
 	if(!val_env->neg_cache)
 		val_env->neg_cache = val_neg_create(cfg,
 			val_env->nsec3_maxiter[val_env->nsec3_keyiter_count-1]);
@@ -196,7 +200,9 @@
 	anchors_delete(env->anchors);
 	env->anchors = NULL;
 	key_cache_delete(val_env->kcache);
+	env->key_cache = NULL;
 	neg_cache_delete(val_env->neg_cache);
+	env->neg_cache = NULL;
 	free(val_env->nsec3_keysize);
 	free(val_env->nsec3_maxiter);
 	free(val_env);
@@ -2242,7 +2248,7 @@
 			!qstate->env->cfg->val_log_squelch) {
 			if(qstate->env->cfg->val_log_level < 2 &&
 				!qstate->env->cfg->log_servfail)
-				log_query_info(0, "validation failure",
+				log_query_info(NO_VERBOSE, "validation failure",
 					&qstate->qinfo);
 			else {
 				char* err = errinf_to_str_bogus(qstate);
--- lib/libunbound/Makefile.orig
+++ lib/libunbound/Makefile
@@ -13,6 +13,7 @@
 PACKAGE=	unbound
 
 CFLAGS+= -I${UNBOUNDDIR} -I${LDNSDIR} -I${.OBJDIR}
+CFLAGS+= -I${SRCTOP}/usr.sbin/unbound
 
 SRCS=	alloc.c as112.c authzone.c autotrust.c cachedb.c config_file.c \
 	configlexer.l configparser.y context.c dname.c dns.c dns64.c \
@@ -23,13 +24,13 @@
 	mesh.c mini_event.c modstack.c module.c msgencode.c msgparse.c \
 	msgreply.c net_help.c netevent.c outbound_list.c outside_network.c \
 	packed_rrset.c parse.c parseutil.c random.c rbtree.c redis.c \
-	regional.c respip.c rrdef.c rrset.c rtt.c sbuffer.c slabhash.c \
+	regional.c respip.c rpz.c rrdef.c rrset.c rtt.c sbuffer.c slabhash.c \
 	str2wire.c tcp_conn_limit.c timehist.c tube.c ub_event_pluggable.c \
 	val_anchor.c val_kcache.c val_kentry.c val_neg.c val_nsec.c \
 	val_nsec3.c val_secalgo.c val_sigcrypt.c val_utils.c validator.c \
 	view.c winsock_event.c wire2str.c
 
-WARNS?=	3
+WARNS?=	2
 NO_WTHREAD_SAFETY= true
 
 LIBADD=	ssl crypto pthread
--- usr.sbin/unbound/anchor/Makefile.orig
+++ usr.sbin/unbound/anchor/Makefile
@@ -10,6 +10,7 @@
 PROG=	local-unbound-anchor
 SRCS=	unbound-anchor.c
 CFLAGS+=	-I${UNBOUNDDIR} -I${LDNSDIR} -I${EXPATDIR}/lib
+CFLAGS+=	-I${.CURDIR:H} -I${.CURDIR}
 LIBADD=	unbound bsdxml ssl crypto pthread
 MAN=	local-unbound-anchor.8
 
--- usr.sbin/unbound/checkconf/Makefile.orig
+++ usr.sbin/unbound/checkconf/Makefile
@@ -9,6 +9,7 @@
 PROG=	local-unbound-checkconf
 SRCS=	ub_event.c unbound-checkconf.c worker_cb.c
 CFLAGS+=	-I${UNBOUNDDIR} -I${LDNSDIR}
+CFLAGS+=	-I${.CURDIR:H} -I${.CURDIR}
 LIBADD=	unbound pthread
 MAN=	local-unbound-checkconf.8
 
--- usr.sbin/unbound/config.h.orig
+++ usr.sbin/unbound/config.h
@@ -0,0 +1,1338 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+/* $FreeBSD$ */
+
+/* apply the noreturn attribute to a function that exits the program */
+#define ATTR_NORETURN __attribute__((__noreturn__))
+
+/* apply the weak attribute to a symbol */
+#define ATTR_WEAK __attribute__((weak))
+
+/* Directory to chroot to */
+#define CHROOT_DIR "/var/unbound"
+
+/* Define this to enable client subnet option. */
+/* #undef CLIENT_SUBNET */
+
+/* Do sha512 definitions in config.h */
+/* #undef COMPAT_SHA512 */
+
+/* Command line arguments used with configure */
+#define CONFCMDLINE "--with-ssl=/usr --with-libexpat=/usr --disable-dnscrypt --disable-dnstap --enable-ecdsa --disable-event-api --enable-gost --with-libevent --disable-subnet --disable-tfo-client --disable-tfo-server --with-pthreads--prefix=/usr --localstatedir=/var/unbound --mandir=/usr/share/man --build=freebsd"
+
+/* Pathname to the Unbound configuration file */
+#define CONFIGFILE "/var/unbound/unbound.conf"
+
+/* Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work
+   */
+/* #undef DARWIN_BROKEN_SETREUID */
+
+/* Whether daemon is deprecated */
+/* #undef DEPRECATED_DAEMON */
+
+/* default dnstap socket path */
+/* #undef DNSTAP_SOCKET_PATH */
+
+/* Define if you want to use debug lock checking (slow). */
+/* #undef ENABLE_LOCK_CHECKS */
+
+/* Define this if you enabled-allsymbols from libunbound to link binaries to
+   it for smaller install size, but the libunbound export table is polluted by
+   internal symbols */
+/* #undef EXPORT_ALL_SYMBOLS */
+
+/* Define to 1 if you have the `accept4' function. */
+#define HAVE_ACCEPT4 1
+
+/* Define to 1 if you have the `arc4random' function. */
+#define HAVE_ARC4RANDOM 1
+
+/* Define to 1 if you have the `arc4random_uniform' function. */
+#define HAVE_ARC4RANDOM_UNIFORM 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Whether the C compiler accepts the "format" attribute */
+#define HAVE_ATTR_FORMAT 1
+
+/* Whether the C compiler accepts the "noreturn" attribute */
+#define HAVE_ATTR_NORETURN 1
+
+/* Whether the C compiler accepts the "unused" attribute */
+#define HAVE_ATTR_UNUSED 1
+
+/* Whether the C compiler accepts the "weak" attribute */
+#define HAVE_ATTR_WEAK 1
+
+/* Define to 1 if you have the `chown' function. */
+#define HAVE_CHOWN 1
+
+/* Define to 1 if you have the `chroot' function. */
+#define HAVE_CHROOT 1
+
+/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */
+
+/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
+/* #undef HAVE_CRYPTO_THREADID_SET_CALLBACK */
+
+/* Define to 1 if you have the `ctime_r' function. */
+#define HAVE_CTIME_R 1
+
+/* Define to 1 if you have the `daemon' function. */
+#define HAVE_DAEMON 1
+
+/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
+   don't. */
+/* #undef HAVE_DECL_ARC4RANDOM */
+
+/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0
+   if you don't. */
+/* #undef HAVE_DECL_ARC4RANDOM_UNIFORM */
+
+/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if
+   you don't. */
+/* #undef HAVE_DECL_EVSIGNAL_ASSIGN */
+
+/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
+   don't. */
+#define HAVE_DECL_INET_NTOP 1
+
+/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you
+   don't. */
+#define HAVE_DECL_INET_PTON 1
+
+/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
+   don't. */
+#define HAVE_DECL_NID_ED25519 1
+
+/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
+   don't. */
+#define HAVE_DECL_NID_ED448 1
+
+/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
+   don't. */
+#define HAVE_DECL_NID_SECP384R1 1
+
+/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0
+   if you don't. */
+#define HAVE_DECL_NID_X9_62_PRIME256V1 1
+
+/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you
+   don't. */
+#define HAVE_DECL_REALLOCARRAY 1
+
+/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
+   don't. */
+/* #undef HAVE_DECL_REDISCONNECT */
+
+/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
+   if you don't. */
+#define HAVE_DECL_SK_SSL_COMP_POP_FREE 1
+
+/* Define to 1 if you have the declaration of
+   `SSL_COMP_get_compression_methods', and to 0 if you don't. */
+#define HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS 1
+
+/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to
+   0 if you don't. */
+#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO 1
+
+/* Define to 1 if you have the declaration of `strlcat', and to 0 if you
+   don't. */
+/* #undef HAVE_DECL_STRLCAT */
+
+/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you
+   don't. */
+/* #undef HAVE_DECL_STRLCPY */
+
+/* Define to 1 if you have the declaration of `XML_StopParser', and to 0 if
+   you don't. */
+#define HAVE_DECL_XML_STOPPARSER 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `DSA_SIG_set0' function. */
+#define HAVE_DSA_SIG_SET0 1
+
+/* Define to 1 if you have the <endian.h> header file. */
+/* #undef HAVE_ENDIAN_H */
+
+/* Define to 1 if you have the `endprotoent' function. */
+#define HAVE_ENDPROTOENT 1
+
+/* Define to 1 if you have the `endpwent' function. */
+#define HAVE_ENDPWENT 1
+
+/* Define to 1 if you have the `endservent' function. */
+#define HAVE_ENDSERVENT 1
+
+/* Define to 1 if you have the `ERR_free_strings' function. */
+/* #undef HAVE_ERR_FREE_STRINGS */
+
+/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
+/* #undef HAVE_ERR_LOAD_CRYPTO_STRINGS */
+
+/* Define to 1 if you have the `event_assign' function. */
+/* #undef HAVE_EVENT_ASSIGN */
+
+/* Define to 1 if you have the `event_base_free' function. */
+/* #undef HAVE_EVENT_BASE_FREE */
+
+/* Define to 1 if you have the `event_base_get_method' function. */
+/* #undef HAVE_EVENT_BASE_GET_METHOD */
+
+/* Define to 1 if you have the `event_base_new' function. */
+/* #undef HAVE_EVENT_BASE_NEW */
+
+/* Define to 1 if you have the `event_base_once' function. */
+/* #undef HAVE_EVENT_BASE_ONCE */
+
+/* Define to 1 if you have the <event.h> header file. */
+/* #undef HAVE_EVENT_H */
+
+/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
+#define HAVE_EVP_AES_256_CBC 1
+
+/* Define to 1 if you have the `EVP_cleanup' function. */
+/* #undef HAVE_EVP_CLEANUP */
+
+/* Define to 1 if you have the `EVP_DigestVerify' function. */
+#define HAVE_EVP_DIGESTVERIFY 1
+
+/* Define to 1 if you have the `EVP_dss1' function. */
+/* #undef HAVE_EVP_DSS1 */
+
+/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
+#define HAVE_EVP_ENCRYPTINIT_EX 1
+
+/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
+#define HAVE_EVP_MD_CTX_NEW 1
+
+/* Define to 1 if you have the `EVP_sha1' function. */
+#define HAVE_EVP_SHA1 1
+
+/* Define to 1 if you have the `EVP_sha256' function. */
+#define HAVE_EVP_SHA256 1
+
+/* Define to 1 if you have the `EVP_sha512' function. */
+#define HAVE_EVP_SHA512 1
+
+/* Define to 1 if you have the `ev_default_loop' function. */
+/* #undef HAVE_EV_DEFAULT_LOOP */
+
+/* Define to 1 if you have the `ev_loop' function. */
+/* #undef HAVE_EV_LOOP */
+
+/* Define to 1 if you have the <expat.h> header file. */
+#define HAVE_EXPAT_H 1
+
+/* Define to 1 if you have the `explicit_bzero' function. */
+#define HAVE_EXPLICIT_BZERO 1
+
+/* Define to 1 if you have the `fcntl' function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the `FIPS_mode' function. */
+#define HAVE_FIPS_MODE 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#define HAVE_FSEEKO 1
+
+/* Define to 1 if you have the `fsync' function. */
+#define HAVE_FSYNC 1
+
+/* Whether getaddrinfo is available */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the `getauxval' function. */
+/* #undef HAVE_GETAUXVAL */
+
+/* Define to 1 if you have the `getentropy' function. */
+/* #undef HAVE_GETENTROPY */
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H 1
+
+/* Define to 1 if you have the `getpwnam' function. */
+#define HAVE_GETPWNAM 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the `glob' function. */
+#define HAVE_GLOB 1
+
+/* Define to 1 if you have the <glob.h> header file. */
+#define HAVE_GLOB_H 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* Define to 1 if you have the <grp.h> header file. */
+#define HAVE_GRP_H 1
+
+/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
+/* #undef HAVE_HIREDIS_HIREDIS_H */
+
+/* Define to 1 if you have the `HMAC_Init_ex' function. */
+#define HAVE_HMAC_INIT_EX 1
+
+/* If you have HMAC_Update */
+#define HAVE_HMAC_UPDATE 1
+
+/* Define to 1 if you have the `inet_aton' function. */
+#define HAVE_INET_ATON 1
+
+/* Define to 1 if you have the `inet_ntop' function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have the `inet_pton' function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the `initgroups' function. */
+#define HAVE_INITGROUPS 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* if the function 'ioctlsocket' is available */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the <iphlpapi.h> header file. */
+/* #undef HAVE_IPHLPAPI_H */
+
+/* Define to 1 if you have the `isblank' function. */
+#define HAVE_ISBLANK 1
+
+/* Define to 1 if you have the `kill' function. */
+#define HAVE_KILL 1
+
+/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
+/* #undef HAVE_LIBKERN_OSBYTEORDER_H */
+
+/* Define if we have LibreSSL */
+/* #undef HAVE_LIBRESSL */
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if you have the <login_cap.h> header file. */
+#define HAVE_LOGIN_CAP_H 1
+
+/* If have GNU libc compatible malloc */
+#define HAVE_MALLOC 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Use libnettle for crypto */
+/* #undef HAVE_NETTLE */
+
+/* Define to 1 if you have the <nettle/dsa-compat.h> header file. */
+/* #undef HAVE_NETTLE_DSA_COMPAT_H */
+
+/* Define to 1 if you have the <nettle/eddsa.h> header file. */
+/* #undef HAVE_NETTLE_EDDSA_H */
+
+/* Use libnss for crypto */
+/* #undef HAVE_NSS */
+
+/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */
+/* #undef HAVE_OPENSSL_ADD_ALL_DIGESTS */
+
+/* Define to 1 if you have the <openssl/bn.h> header file. */
+#define HAVE_OPENSSL_BN_H 1
+
+/* Define to 1 if you have the `OPENSSL_config' function. */
+#define HAVE_OPENSSL_CONFIG 1
+
+/* Define to 1 if you have the <openssl/conf.h> header file. */
+#define HAVE_OPENSSL_CONF_H 1
+
+/* Define to 1 if you have the <openssl/dh.h> header file. */
+#define HAVE_OPENSSL_DH_H 1
+
+/* Define to 1 if you have the <openssl/dsa.h> header file. */
+#define HAVE_OPENSSL_DSA_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#define HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
+#define HAVE_OPENSSL_INIT_CRYPTO 1
+
+/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
+#define HAVE_OPENSSL_INIT_SSL 1
+
+/* Define to 1 if you have the <openssl/rand.h> header file. */
+#define HAVE_OPENSSL_RAND_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#define HAVE_PTHREAD_PRIO_INHERIT 1
+
+/* Define to 1 if the system has the type `pthread_rwlock_t'. */
+#define HAVE_PTHREAD_RWLOCK_T 1
+
+/* Define to 1 if the system has the type `pthread_spinlock_t'. */
+#define HAVE_PTHREAD_SPINLOCK_T 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define if you have Python libraries and header files. */
+/* #undef HAVE_PYTHON */
+
+/* Define to 1 if you have the `random' function. */
+#define HAVE_RANDOM 1
+
+/* Define to 1 if you have the `RAND_cleanup' function. */
+/* #undef HAVE_RAND_CLEANUP */
+
+/* If we have reallocarray(3) */
+#define HAVE_REALLOCARRAY 1
+
+/* Define to 1 if you have the `recvmsg' function. */
+#define HAVE_RECVMSG 1
+
+/* Define to 1 if you have the `sendmsg' function. */
+#define HAVE_SENDMSG 1
+
+/* Define to 1 if you have the `setregid' function. */
+/* #undef HAVE_SETREGID */
+
+/* Define to 1 if you have the `setresgid' function. */
+#define HAVE_SETRESGID 1
+
+/* Define to 1 if you have the `setresuid' function. */
+#define HAVE_SETRESUID 1
+
+/* Define to 1 if you have the `setreuid' function. */
+/* #undef HAVE_SETREUID */
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the `setsid' function. */
+#define HAVE_SETSID 1
+
+/* Define to 1 if you have the `setusercontext' function. */
+#define HAVE_SETUSERCONTEXT 1
+
+/* Define to 1 if you have the `SHA512_Update' function. */
+/* #undef HAVE_SHA512_UPDATE */
+
+/* Define to 1 if you have the `shmget' function. */
+#define HAVE_SHMGET 1
+
+/* Define to 1 if you have the `sigprocmask' function. */
+#define HAVE_SIGPROCMASK 1
+
+/* Define to 1 if you have the `sleep' function. */
+#define HAVE_SLEEP 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `socketpair' function. */
+#define HAVE_SOCKETPAIR 1
+
+/* Using Solaris threads */
+/* #undef HAVE_SOLARIS_THREADS */
+
+/* Define to 1 if you have the `srandom' function. */
+#define HAVE_SRANDOM 1
+
+/* Define if you have the SSL libraries installed. */
+#define HAVE_SSL /**/
+
+/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
+#define HAVE_SSL_CTX_SET_CIPHERSUITES 1
+
+/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
+#define HAVE_SSL_CTX_SET_SECURITY_LEVEL 1
+
+/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
+/* #undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB */
+
+/* Define to 1 if you have the `SSL_get0_peername' function. */
+#define HAVE_SSL_GET0_PEERNAME 1
+
+/* Define to 1 if you have the `SSL_set1_host' function. */
+#define HAVE_SSL_SET1_HOST 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+#define HAVE_STRLCAT 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#define HAVE_STRLCPY 1
+
+/* Define to 1 if you have the `strptime' function. */
+#define HAVE_STRPTIME 1
+
+/* Define to 1 if you have the `strsep' function. */
+#define HAVE_STRSEP 1
+
+/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
+/* #undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST */
+
+/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
+#define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1
+
+/* Define if you have Swig libraries and header files. */
+/* #undef HAVE_SWIG */
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if systemd should be used */
+/* #undef HAVE_SYSTEMD */
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+#define HAVE_SYS_ENDIAN_H 1
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+#define HAVE_SYS_IPC_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/sha2.h> header file. */
+/* #undef HAVE_SYS_SHA2_H */
+
+/* Define to 1 if you have the <sys/shm.h> header file. */
+#define HAVE_SYS_SHM_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+/* #undef HAVE_SYS_SYSCTL_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the `tzset' function. */
+#define HAVE_TZSET 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `usleep' function. */
+#define HAVE_USLEEP 1
+
+/* Define to 1 if you have the `vfork' function. */
+#define HAVE_VFORK 1
+
+/* Define to 1 if you have the <vfork.h> header file. */
+/* #undef HAVE_VFORK_H */
+
+/* Define to 1 if you have the <windows.h> header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Using Windows threads */
+/* #undef HAVE_WINDOWS_THREADS */
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if `fork' works. */
+#define HAVE_WORKING_FORK 1
+
+/* Define to 1 if `vfork' works. */
+#define HAVE_WORKING_VFORK 1
+
+/* Define to 1 if you have the `writev' function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the <ws2tcpip.h> header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
+#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1
+
+/* Define to 1 if you have the `_beginthreadex' function. */
+/* #undef HAVE__BEGINTHREADEX */
+
+/* If HMAC_Init_ex() returns void */
+/* #undef HMAC_INIT_EX_RETURNS_VOID */
+
+/* if lex has yylex_destroy */
+#define LEX_HAS_YYLEX_DESTROY 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to the maximum message length to pass to syslog. */
+#define MAXSYSLOGMSGLEN 10240
+
+/* Define if memcmp() does not compare unsigned bytes */
+/* #undef MEMCMP_IS_BROKEN */
+
+/* Define if mkdir has one argument. */
+/* #undef MKDIR_HAS_ONE_ARG */
+
+/* Define if the network stack does not fully support nonblocking io (causes
+   lower performance). */
+/* #undef NONBLOCKING_IS_BROKEN */
+
+/* Put -D_ALL_SOURCE define in config.h */
+/* #undef OMITTED__D_ALL_SOURCE */
+
+/* Put -D_BSD_SOURCE define in config.h */
+/* #undef OMITTED__D_BSD_SOURCE */
+
+/* Put -D_DEFAULT_SOURCE define in config.h */
+/* #undef OMITTED__D_DEFAULT_SOURCE */
+
+/* Put -D_GNU_SOURCE define in config.h */
+/* #undef OMITTED__D_GNU_SOURCE */
+
+/* Put -D_LARGEFILE_SOURCE=1 define in config.h */
+/* #undef OMITTED__D_LARGEFILE_SOURCE_1 */
+
+/* Put -D_POSIX_C_SOURCE=200112 define in config.h */
+/* #undef OMITTED__D_POSIX_C_SOURCE_200112 */
+
+/* Put -D_XOPEN_SOURCE=600 define in config.h */
+/* #undef OMITTED__D_XOPEN_SOURCE_600 */
+
+/* Put -D_XOPEN_SOURCE_EXTENDED=1 define in config.h */
+/* #undef OMITTED__D_XOPEN_SOURCE_EXTENDED_1 */
+
+/* Put -D__EXTENSIONS__ define in config.h */
+/* #undef OMITTED__D__EXTENSIONS__ */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "unbound"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "unbound 1.10.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "unbound"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.10.1"
+
+/* default pidfile location */
+#define PIDFILE "/var/unbound/unbound.pid"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* if REUSEPORT is enabled by default */
+#define REUSEPORT_DEFAULT 0
+
+/* default rootkey location */
+#define ROOT_ANCHOR_FILE "/var/unbound/root.key"
+
+/* default rootcert location */
+#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem"
+
+/* version number for resource files */
+#define RSRC_PACKAGE_VERSION 1,9,6,0
+
+/* Directory to chdir to */
+#define RUN_DIR "/var/unbound"
+
+/* Shared data */
+#define SHARE_DIR "/var/unbound"
+
+/* The size of `size_t'. */
+#ifdef  __LP64__
+#define SIZEOF_SIZE_T 8
+#else
+#define SIZEOF_SIZE_T 4
+#endif
+
+/* The size of `time_t', as computed by sizeof. */
+#ifdef  __i386__
+#define SIZEOF_TIME_T 4
+#else
+#define SIZEOF_TIME_T 8
+#endif
+
+/* define if (v)snprintf does not return length needed, (but length used) */
+/* #undef SNPRINTF_RET_BROKEN */
+
+/* Define to 1 if libsodium supports sodium_set_misuse_handler */
+/* #undef SODIUM_MISUSE_HANDLER */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* use default strptime. */
+#define STRPTIME_WORKS 1
+
+/* Use win32 resources and API */
+/* #undef UB_ON_WINDOWS */
+
+/* the SYSLOG_FACILITY to use, default LOG_DAEMON */
+#define UB_SYSLOG_FACILITY LOG_DAEMON
+
+/* default username */
+#define UB_USERNAME "unbound"
+
+/* use to enable lightweight alloc assertions, for debug use */
+/* #undef UNBOUND_ALLOC_LITE */
+
+/* use malloc not regions, for debug use */
+/* #undef UNBOUND_ALLOC_NONREGIONAL */
+
+/* use statistics for allocs and frees, for debug use */
+/* #undef UNBOUND_ALLOC_STATS */
+
+/* define this to enable debug checks. */
+/* #undef UNBOUND_DEBUG */
+
+/* Define to 1 to use cachedb support */
+/* #undef USE_CACHEDB */
+
+/* Define to 1 to enable dnscrypt support */
+/* #undef USE_DNSCRYPT */
+
+/* Define to 1 to enable dnscrypt with xchacha20 support */
+/* #undef USE_DNSCRYPT_XCHACHA20 */
+
+/* Define to 1 to enable dnstap support */
+/* #undef USE_DNSTAP */
+
+/* Define this to enable DSA support. */
+#define USE_DSA 1
+
+/* Define this to enable ECDSA support. */
+#define USE_ECDSA 1
+
+/* Define this to enable an EVP workaround for older openssl */
+/* #undef USE_ECDSA_EVP_WORKAROUND */
+
+/* Define this to enable ED25519 support. */
+#define USE_ED25519 1
+
+/* Define this to enable ED448 support. */
+#define USE_ED448 1
+
+/* Define this to enable GOST support. */
+/* #undef USE_GOST */
+
+/* Define to 1 to use ipsecmod support. */
+/* #undef USE_IPSECMOD */
+
+/* Define to 1 to use ipset support */
+/* #undef USE_IPSET */
+
+/* Define if you want to use internal select based events */
+#define USE_MINI_EVENT 1
+
+/* Define this to enable client TCP Fast Open. */
+/* #undef USE_MSG_FASTOPEN */
+
+/* Define this to enable client TCP Fast Open. */
+/* #undef USE_OSX_MSG_FASTOPEN */
+
+/* Define this to use hiredis client. */
+/* #undef USE_REDIS */
+
+/* Define this to enable SHA1 support. */
+#define USE_SHA1 1
+
+/* Define this to enable SHA256 and SHA512 support. */
+#define USE_SHA2 1
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
+/* Define this to enable server TCP Fast Open. */
+/* #undef USE_TCP_FASTOPEN */
+
+/* Whether the windows socket API is used */
+/* #undef USE_WINSOCK */
+
+/* the version of the windows API enabled */
+#define WINVER 0x0502
+
+/* Define if you want Python module. */
+/* #undef WITH_PYTHONMODULE */
+
+/* Define if you want PyUnbound. */
+/* #undef WITH_PYUNBOUND */
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+   `char[]'. */
+#define YYTEXT_POINTER 1
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+/* #undef _LARGEFILE_SOURCE */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Enable for compile on Minix */
+/* #undef _NETBSD_SOURCE */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* in_addr_t */
+/* #undef in_addr_t */
+
+/* in_port_t */
+/* #undef in_port_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `short' if <sys/types.h> does not define. */
+/* #undef int16_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef int32_t */
+
+/* Define to `long long' if <sys/types.h> does not define. */
+/* #undef int64_t */
+
+/* Define to `signed char' if <sys/types.h> does not define. */
+/* #undef int8_t */
+
+/* Define if replacement function should be used. */
+/* #undef malloc */
+
+/* Define to `long int' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to 'int' if not defined */
+/* #undef rlim_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to 'int' if not defined */
+/* #undef socklen_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef ssize_t */
+
+/* Define to 'unsigned char if not defined */
+/* #undef u_char */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+/* Define to `unsigned short' if <sys/types.h> does not define. */
+/* #undef uint16_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef uint32_t */
+
+/* Define to `unsigned long long' if <sys/types.h> does not define. */
+/* #undef uint64_t */
+
+/* Define to `unsigned char' if <sys/types.h> does not define. */
+/* #undef uint8_t */
+
+/* Define as `fork' if `vfork' does not work. */
+/* #undef vfork */
+
+#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE)
+#define _GNU_SOURCE 1
+#endif 
+
+#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE)
+#define _BSD_SOURCE 1
+#endif 
+
+#if defined(OMITTED__D_DEFAULT_SOURCE) && !defined(_DEFAULT_SOURCE)
+#define _DEFAULT_SOURCE 1
+#endif 
+
+#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__)
+#define __EXTENSIONS__ 1
+#endif 
+
+#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 200112
+#endif 
+
+#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE)
+#define _XOPEN_SOURCE 600
+#endif 
+
+#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED)
+#define _XOPEN_SOURCE_EXTENDED 1
+#endif 
+
+#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE)
+#define _ALL_SOURCE 1
+#endif 
+
+#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE)
+#define _LARGEFILE_SOURCE 1
+#endif 
+
+
+
+
+#ifndef _OPENBSD_SOURCE
+#define _OPENBSD_SOURCE 1
+#endif
+
+#ifndef UNBOUND_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+/** Use small-ldns codebase */
+#define USE_SLDNS 1
+#ifdef HAVE_SSL
+#  define LDNS_BUILD_CONFIG_HAVE_SSL 1
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include <errno.h>
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+
+#ifndef USE_WINSOCK
+#define ARG_LL "%ll"
+#else
+#define ARG_LL "%I64"
+#endif
+
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
+
+
+ 
+#ifdef HAVE_ATTR_FORMAT
+#  define ATTR_FORMAT(archetype, string_index, first_to_check) \
+    __attribute__ ((format (archetype, string_index, first_to_check)))
+#else /* !HAVE_ATTR_FORMAT */
+#  define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
+#endif /* !HAVE_ATTR_FORMAT */
+
+
+#if defined(DOXYGEN)
+#  define ATTR_UNUSED(x)  x
+#elif defined(__cplusplus)
+#  define ATTR_UNUSED(x)
+#elif defined(HAVE_ATTR_UNUSED)
+#  define ATTR_UNUSED(x)  x __attribute__((unused))
+#else /* !HAVE_ATTR_UNUSED */
+#  define ATTR_UNUSED(x)  x
+#endif /* !HAVE_ATTR_UNUSED */
+
+
+#ifndef HAVE_FSEEKO
+#define fseeko fseek
+#define ftello ftell
+#endif /* HAVE_FSEEKO */
+
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
+#define snprintf snprintf_unbound
+#define vsnprintf vsnprintf_unbound
+#include <stdarg.h>
+int snprintf (char *str, size_t count, const char *fmt, ...);
+int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+#endif /* HAVE_SNPRINTF or SNPRINTF_RET_BROKEN */
+
+#ifndef HAVE_INET_PTON
+#define inet_pton inet_pton_unbound
+int inet_pton(int af, const char* src, void* dst);
+#endif /* HAVE_INET_PTON */
+
+
+#ifndef HAVE_INET_NTOP
+#define inet_ntop inet_ntop_unbound
+const char *inet_ntop(int af, const void *src, char *dst, size_t size);
+#endif
+
+
+#ifndef HAVE_INET_ATON
+#define inet_aton inet_aton_unbound
+int inet_aton(const char *cp, struct in_addr *addr);
+#endif
+
+
+#ifndef HAVE_MEMMOVE
+#define memmove memmove_unbound
+void *memmove(void *dest, const void *src, size_t n);
+#endif
+
+
+#ifndef HAVE_STRLCAT
+#define strlcat strlcat_unbound
+size_t strlcat(char *dst, const char *src, size_t siz);
+#endif
+
+
+#ifndef HAVE_STRLCPY
+#define strlcpy strlcpy_unbound
+size_t strlcpy(char *dst, const char *src, size_t siz);
+#endif
+
+
+#ifndef HAVE_GMTIME_R
+#define gmtime_r gmtime_r_unbound
+struct tm *gmtime_r(const time_t *timep, struct tm *result);
+#endif
+
+
+#ifndef HAVE_REALLOCARRAY
+#define reallocarray reallocarrayunbound
+void* reallocarray(void *ptr, size_t nmemb, size_t size);
+#endif
+
+
+#if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H)
+#define sleep(x) Sleep((x)*1000) /* on win32 */
+#endif /* HAVE_SLEEP */
+
+
+#ifndef HAVE_USLEEP
+#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */
+#endif /* HAVE_USLEEP */
+
+
+#ifndef HAVE_RANDOM
+#define random rand /* on win32, for tests only (bad random) */
+#endif /* HAVE_RANDOM */
+
+
+#ifndef HAVE_SRANDOM
+#define srandom(x) srand(x) /* on win32, for tests only (bad random) */
+#endif /* HAVE_SRANDOM */
+
+
+/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
+#ifdef HAVE_WINSOCK2_H
+#define FD_SET_T (u_int)
+#else
+#define FD_SET_T 
+#endif
+
+
+#ifndef IPV6_MIN_MTU
+#define IPV6_MIN_MTU 1280
+#endif /* IPV6_MIN_MTU */
+
+
+#ifdef MEMCMP_IS_BROKEN
+#include "compat/memcmp.h"
+#define memcmp memcmp_unbound
+int memcmp(const void *x, const void *y, size_t n);
+#endif
+
+
+
+#ifndef HAVE_CTIME_R
+#define ctime_r unbound_ctime_r
+char *ctime_r(const time_t *timep, char *buf);
+#endif
+
+#ifndef HAVE_STRSEP
+#define strsep unbound_strsep
+char *strsep(char **stringp, const char *delim);
+#endif
+
+#ifndef HAVE_ISBLANK
+#define isblank unbound_isblank
+int isblank(int c);
+#endif
+
+#ifndef HAVE_EXPLICIT_BZERO
+#define explicit_bzero unbound_explicit_bzero
+void explicit_bzero(void* buf, size_t len);
+#endif
+
+#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
+const char *inet_ntop(int af, const void *src, char *dst, size_t size);
+#endif
+
+#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
+int inet_pton(int af, const char* src, void* dst);
+#endif
+
+#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
+#define strptime unbound_strptime
+struct tm;
+char *strptime(const char *s, const char *format, struct tm *tm);
+#endif
+
+#if !HAVE_DECL_REALLOCARRAY
+void *reallocarray(void *ptr, size_t nmemb, size_t size);
+#endif
+
+#ifdef HAVE_LIBRESSL
+#  if !HAVE_DECL_STRLCPY
+size_t strlcpy(char *dst, const char *src, size_t siz);
+#  endif
+#  if !HAVE_DECL_STRLCAT
+size_t strlcat(char *dst, const char *src, size_t siz);
+#  endif
+#  if !HAVE_DECL_ARC4RANDOM && defined(HAVE_ARC4RANDOM)
+uint32_t arc4random(void);
+#  endif
+#  if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
+uint32_t arc4random_uniform(uint32_t upper_bound);
+#  endif
+#endif /* HAVE_LIBRESSL */
+#ifndef HAVE_ARC4RANDOM
+int getentropy(void* buf, size_t len);
+uint32_t arc4random(void);
+void arc4random_buf(void* buf, size_t n);
+void _ARC4_LOCK(void);
+void _ARC4_UNLOCK(void);
+void _ARC4_LOCK_DESTROY(void);
+#endif
+#ifndef HAVE_ARC4RANDOM_UNIFORM
+uint32_t arc4random_uniform(uint32_t upper_bound);
+#endif
+#ifdef COMPAT_SHA512
+#ifndef SHA512_DIGEST_LENGTH
+#define SHA512_BLOCK_LENGTH		128
+#define SHA512_DIGEST_LENGTH		64
+#define SHA512_DIGEST_STRING_LENGTH	(SHA512_DIGEST_LENGTH * 2 + 1)
+typedef struct _SHA512_CTX {
+	uint64_t	state[8];
+	uint64_t	bitcount[2];
+	uint8_t	buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+#endif /* SHA512_DIGEST_LENGTH */
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, void*, size_t);
+void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest);
+#endif /* COMPAT_SHA512 */
+
+
+
+#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
+   /* using version of libevent that is not threadsafe. */
+#  define LIBEVENT_SIGNAL_PROBLEM 1
+#endif
+
+#ifndef CHECKED_INET6
+#  define CHECKED_INET6
+#  ifdef AF_INET6
+#    define INET6
+#  else
+#    define AF_INET6        28
+#  endif
+#endif /* CHECKED_INET6 */
+
+#ifndef HAVE_GETADDRINFO
+struct sockaddr_storage;
+#include "compat/fake-rfc2553.h"
+#endif
+
+#ifdef UNBOUND_ALLOC_STATS
+#  define malloc(s) unbound_stat_malloc_log(s, __FILE__, __LINE__, __func__)
+#  define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
+#  define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
+#  define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
+void *unbound_stat_malloc(size_t size);
+void *unbound_stat_calloc(size_t nmemb, size_t size);
+void unbound_stat_free(void *ptr);
+void *unbound_stat_realloc(void *ptr, size_t size);
+void *unbound_stat_malloc_log(size_t size, const char* file, int line,
+	const char* func);
+void *unbound_stat_calloc_log(size_t nmemb, size_t size, const char* file,
+	int line, const char* func);
+void unbound_stat_free_log(void *ptr, const char* file, int line,
+	const char* func);
+void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
+	int line, const char* func);
+#elif defined(UNBOUND_ALLOC_LITE)
+#  include "util/alloc.h"
+#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
+
+/** default port for DNS traffic. */
+#define UNBOUND_DNS_PORT 53
+/** default port for DNS over TLS traffic. */
+#define UNBOUND_DNS_OVER_TLS_PORT 853
+/** default port for unbound control traffic, registered port with IANA,
+    ub-dns-control  8953/tcp    unbound dns nameserver control */
+#define UNBOUND_CONTROL_PORT 8953
+/** the version of unbound-control that this software implements */
+#define UNBOUND_CONTROL_VERSION 1
+
+
--- usr.sbin/unbound/control/Makefile.orig
+++ usr.sbin/unbound/control/Makefile
@@ -9,6 +9,7 @@
 PROG=	local-unbound-control
 SRCS=	ub_event.c unbound-control.c worker_cb.c
 CFLAGS+=	-I${UNBOUNDDIR} -I${LDNSDIR}
+CFLAGS+=	-I${.CURDIR:H} -I${.CURDIR}
 LIBADD=	unbound crypto ssl pthread
 MAN=	local-unbound-control.8
 
--- usr.sbin/unbound/daemon/Makefile.orig
+++ usr.sbin/unbound/daemon/Makefile
@@ -10,6 +10,7 @@
 SRCS=	acl_list.c cachedump.c daemon.c remote.c shm_main.c stats.c \
 	ub_event.c unbound.c worker.c
 CFLAGS+=	-I${UNBOUNDDIR} -I${LDNSDIR}
+CFLAGS+=	-I${.CURDIR:H} -I${.CURDIR}
 LIBADD=	unbound util ssl crypto pthread
 MAN=	local-unbound.8 local-unbound.conf.5
 
